  '----------------
  #macro chareval()
  '================
  b=i
  c=i
  d=ascn
  if d=lbr then
    c=i+1 : nextinstruct(s,c) : m=1
  end if
  'number literals
  'itr equates ?
  if isn(ascn) then
    i=c
    w1="" 'byte accumulator
    c=0 'byte length counter
    do
      wordval(s,i,i)
      c+=1
      w1+=hexb(dv)
      select case ascn
      case 44
        i+=1 : nextinstruct(s,i)
        continue do
      case 41
        if m then i+=1 : skiplspace(s,i)
      case 48 to 57
        continue do
      case 0 to 47
        goto revertchr
      end select
      'termination
      w1+=hexb(0) 'terminating null
      wpfx+=stodat(w1,c) : wr=cpua
      typ=&hc1 : typa=typ
      goto cvtop
    loop
  end if
  revertchr:
  i=b : ascn=d : goto procedcall
  #endmacro


  '-------------------------------------
  function expandmac(f as sys) as string
  '=====================================
  if (tranpass=1)or(compact<>0) then exit function
  dim as sys a=1, c=0
  dim as string w1,w2
  w2=macso(f,1)
  do 'expand macro recursively
    a=instr(a,w2,"%")
    if a=0 then exit do
    a+=1
    w1=tword(w2,a)
    c=lookupm(w1)
    if c then
      w2=left(w2,swd-2)+macso(c,1)+mid(w2,a)
    else
      ert=1003 : ers="unidentified macro in deff: %" + w1
      exit do
    end if
  loop
  return w2+cr
  end function

  'CONVERT NUMERIC ACCUM TO STRING ACCUM
  '
  '----------------------------------------------------
  function numtostr(typa1 as sys,typa as sys) as string
  '====================================================
  dim as sys c
  dim as string wt
  if typa<&h80 then 'CONVERT NUM ACCUM TO STRING APPEND
    if jn then c=43 else c=1
    wt=cvtai(typa,&hc1) 'VAL TO STRING THEN APPEND
    if (c=43)or(isstr(typa1)=0)or(parx>0) then
      wt+=logas() 'LOG TEMP STRING FOR DELETION
    end if
    wt+=operi(c,&hc1,"")
  end if
  function=wt
  end function
  '
  '
  '
  '
  '  #################
  ' #### EXPRESSIONS ##
  ' ##################
  ' ###
  ' ###
  ' ###          ###   ###
  ' ###            #   #
  ' ###########     # #    ####   ###
  ' ############     #     #   # #  
  ' ###########     # #    ####  #
  ' ###            #   #   #     #
  ' ###          ###   ### #     #
  ' ###
  ' ###
  ' ##################
  ' ###################
  '  #################
  '
  '
  '---------------------------------------------------------------------------------
  function express( byref s as string, byref i as sys, byref typa1 as sys) as string
  '=================================================================================
  '
  dim as sys    a,b,c,d,e,f,m,r,n,v,typa,typc,opo,cp,tp,clbr,cbj,qp,pid,ctop
  dim as sys    nsl,ofpu,noto,fxsq,ocp,omp,ojn,uex,usx,aint,ainv,pargl
  dim as sys    xmode,xoffs
  dim as string w1,w2,w3,w4,w5,w6,wr,wt,wp
  dim as string ains,wra,memba,membb,wpfxa,xcalc

  static as sys    po(8)
  static as string wc(8),laz
  static as double dw=&h7fffffff
  '
  '
  if nst=0 then
    '
    if op=-1 then
      w2=mid(s,i,1)
      i+=1
    elseif typa1 then
      expandexpr(s,i,typa1) 'EXPAND IIF EXPRESIONS: AA=(A>B ? C : D )
      if rps=2 then
        if typa1>=htyp then
          owa=aword(s,i) : goto exitexpr
        end if
      end if
    end if
    '
    w1=w2+precedence(s,i,0)
    inserts(s,w1,i)
    skiplspace(s,i)
    '
    if divi then
      fpu=1 'prefer floating point when expression contains "/"
    end if
  end if
  '
  da=0 : cp=0 : nsl=nst : ascw=0 : e=1 : bvg=0 : stk.c=0
  '
  skiplspace(s,i)
  '
  'IF (A==B) ++C;
  '
  if cnd then
    if nst=0 then
      if (ascn=lbr)and(sr2=59) then
        clbr=1 'C STYLE CONDITIONAL (CONF: #SEMICOLON SEPARATOR)
      end if
    end if 
  end if
  '
  if fpu>0 then
    typc=&h68 ' FPU PREFERRED
  elseif fpu<0 then
    typc=cpuw ' CPU PREFERRED
  else
    typc=typa1
  end if
  '
  if asgm then
    if typc>=htyp then typc=cpuw 'FOR MULTI-ASSIGNMENTS
  end if
  '
  '
  'EMPTY EXPRESSION TERMINATED BY COMMA OR RIGHT BRACKET , ) ]
  '
  if (ascn=44)or(ascn=rbr)or(ascn=93) then
    typc=cpuw : wr="0" : op=1 : wt+=operi(op,typc,wr)
    goto nassignt
  end if
  '
  '
  '=======
   oploop:
  '=======
  '
  select case typc
  case &he0 to &hff
    typc-=32 'set as BSTR BY VALUE
  end select
  '
  select case op
  case -1
    typc=typa1 : op=0 : goto nestpush 'ARRAY INDEX EVALUATION
  case -2
    typc=typa1 : goto nextops  'OPERATOR OR TERMINATOR EXPECTED
  case 47 '/
    if typc<&h40 then
      wt+=cvtai(typc,&h68) : typc=&h68
    end if
  end select
  '
  wr=pword(s,i)
  '
  if ascw=99 then '
    if wr="convert" then
      a=99 : wr=pword(s,i)
      if wr="string" then
        typ=&hc1 'override string() function
      end if
    end if
  end if
  if (mc=-3)or(mc=-15)or(mc=-8)or(a=99) then
    if op<=1 then
      if typa1=0 then typa1=typ
      typc=typ
    end if
    uex=1024
    wr=pword(s,i)
  end if 
  if ascw=0 then
    ers="unexpected end of prog" : ert=9
    goto exitexpr
  end if
  '
#if 0
  if (mc=-3)or(mc=-15)or(mc=-8) then
    if op<=1 then
      if typa1=0 then typa1=typ
      typc=typ
    end if
    uex=1024
    a=typ
    wr=pword(s,i)
    typ=a
  end if 
  '
  if ascw=0 then
    ers="unexpected end of prog" : ert=9
    goto exitexpr
  elseif ascw=99 then 'c
    if wr="convert" then
      wr=pword(s,i)
      a=identype(wr)
      if a then
        rps=4
        wr=NewTmpVar(wr)
        hiex+=wr+"="+captsx(s,i)+cr
        inserts(s,wr,i)
        wr=pword(s,i)
      end if
    end if
  end if
#endif
  '
  if ert then goto nassignt
  '
  if cpoint then
    if typ>=htyp then typ=cpuw
  end if
  '
  '
  typa=typ
  '
  '
  'HIGHER TYPES
  '
  if (typ>=htyp) then
    typc=typ 'CAST ACCUM
    if asgm then
       goto multiassigns
    end if
    if varf>8 then goto procedcall 'METHOD RETURNING HIGHER TYPE
    if (parx>0)and(isxn) then
      wt+=wpfx+"lea "+qeax+cm+wr+cr 'RETURN WITH ADDRESS
      goto nassignt
    end if
    'OTHERWISE INSERT RPS CODE
    inserts(s,owa+" ",i) 'STEP BACK
    MixHigherExpr(s,i,wt,typc,0)
    typa=typ 'SET BY LAST TEMP VAR
    typc=cpuw
    goto nextops
  elseif ascn=lbr then
    'HIGHER PROCEDURES / MACROS WIH HIGHER PARAMS
    a=TypeHigherExpr(s,i,ow,c)
    if a+asgm=0 then
      if typa1>=htyp then a=typa1
    end if
    if a then
      inserts(s,owa+" ",i) 'STEP BACK
      MixHigherExpr(s,i,wt,a,c)
      typa=typ
      if typc=0 then typc=typa
      goto nextops
    end if
  end if
  '
  select case ascw
  case &h63 'c'
    if wr="call" then
      nobr=1
      c=typk
      do
        if wr="call" then wr=pword(s,i) else exit do
      loop
      typk=c
      nobr=0
      varf=8
      goto procedcall
    elseif wr="chr" then
      chareval() 'macro
    end if
  case &h6e 'n'
    if wr="null" then
      bvg=1 'always accept as param
      wr="0"
      typc=typa1
      if cnd=0 then
        wt+=operi(1,cpuw,"0")
        goto nassignt
      end if
    elseif wr="not" then
      noto=1-noto : goto oploop 'continue do
    end if
  case 95 '_'
    if wr="_neg" then
      wt+=operi(7,typc,"")
      goto nextops
    end if
  case 43 to 45
    '
    'CHECK PRE INCREMENT / DECREMENT ++ --
    '
    if (ascw=43)or(ascw=45) then
      if ascw=asc(s,swd+1) then
        if ascw=43 then a=12 else a=13
        i+=1 : wr=pword(s,i) '++A --A
        if cpoint then
          if typ>=htyp then typ=cpuw
        end if
        wpfx+=operi(a,typ,wr) 'USES LENT TO STEP
        if ert then goto exitexpr
      end if
      if (ascw=45)and(mc<>-31) then
        op=1
        if ascn=lbr then
          a=i : capture(s,m,i,0)
          w1=mid(s,a,i-a)
          inserts(s,w1+" _neg ",i)
          goto oploop
        else
          wr=pword(s,i)
          if ascn=lbr then
            a=i : capture(s,m,i,0)
            w1=mid(s,a,i-a)
            inserts(s,w1+" _neg ",i)
          else  
            inserts(s,"_neg ",i)
          end if
        end if
      end if
    end if
  case 123 '{'
    if asgm then asgm+=1 : goto oploop 'MULTIASSIGN INNER {
  case 42 to 255
    '
  case 40
    goto nestpush
  case 41 ')'
    goto nestpop
  case 37
    goto oploop 'IGNORE % IN EXPRESSION
  end select 'ascw
  '
  '
  ' (A>B) SIMPLE STRING COMPARATORS OPTIM
  '======================================
  '
  if (ascn=rbr)and(cp<>0)and(op<2) then
    if (isstr(typ))and(isstr(tp)) then
      wt+=makestrptrfun(wr)
      goto oploop
    end if
  end if
  '
  '
  select case mc
  '
  case 0
    'variables
  case -5 to -4
    goto procedcall
  case -10
    goto cvtop 'regs
  case -15 'PRIMITIVE TYPE
    'EXPLICITLY CHANGE ACCUM TYPE 'a=double b + 7
    if typa1=0 then
      if op<2 then
        typ=identype(wr) : typa1=typ : typc=typ 'force expression type
      end if
    end if
    goto oploop
  case -16
    goto procedcall
  case -17
    if typc<&ha0 then goto floatmacros
  case -30
    goto cvtop 'LABELS
  case -31
    '
    'LITERAL NUMBERS
    '
    if nan=0 then
      '
      'TYPE CONVERSIONS
      '
      if typc=0 then
        typc=typ 'SET ACCUM TYPE (LONG)
      elseif isfpu(typc) then
        typ=typc 'TREAT AS FLOAT
      elseif typc<&h40 then
        if typ=&h68 then
          if op>1 then wt+=cvtai(typc,&h68) 'UPGRADE ACCUM
          typc=&h68
        else
          typ=typc 'MATCH INTEGER ACCUM TYPE
        end if
      end if
      '
      typa=typ
      '
    end if
  case -32  'STRING LITERAL
    goto cvtop
  end select 'mc
  '
  '
  if mp+parx=0 then
    if isa(ascw) then
      if ow=wr then
        ers="Unidentified operand" : ert=100 : goto nassignt
      end if
    end if
  end if
  '
  'CONVERT STRING ACCUM TO NUMERIC ACCUM
  '=====================================
  '
  'STRING ACCUMULATOR BUT FLOAT MACRO OR NUMERIC OPERAND
  '
  if isstr(typc) then
    typa=typ
    if funi then lcls=1
    if (mc=-17) then 'FLOAT MACRO
      typc=&h68
      fpu=1
      op=1
      uex=1024 'SIGNAL TO USE FULL EXPRESSION
    elseif (typa>0)and(typa<&h80) then 'NUMBER
      op=1
      typc=typa
      if typc<&h40 then
        if lent<cpuw then typc=4 'INT ACCUM
      else
        fpu=1
        typc=&h68 'FLOAT ACCUM
      end if
      uex=1024 'SIGNAL TO USE FULL EXPRESSION
    end if
  end if
  '
  '
  '===========================
  procedcall: 'PROCEDURE CALLS
  '===========================
  '
  if typ=0 then
    if (nst<1)and(typa1<>0) then typ=typa1 else typ=cpuw ' ADOPT ASSIGNMENT TYPE
  end if
  '
  typa=typ
  '
  n=0
  '
  '
  if varf>7 then
    '
    'PRELIM CHECKS
    '-------------
    '
    if ascw=&h63 then
      if wr="compile" then
        if pef then a=mesb else a=mest
        w1="`readstate "+iq+writestates(a,me-1)+iq+"` "
        inserts(s,w1,i)
        'EMBEDS STATE DATA BEFORE INLINE RUNTIME COMPILING
        wt+=operi(4,cpuw,qebx) 'pass .bssdata address (becomes last param)
        if tranpass=2 then depsp+=&h1000 'allocate extra static space for run-time compiling
      end if
    end if
    '
    '
    'PARAMS WILL BE RESOLVED RECURSIVELY (procedures calls express)
    '--------------------------------------------------------------
    '
    if op<=1 then
      if ascn=95 then
        if wordahead(s,i)="_neg" then
          op=7 'neg load
        end if
      end if
    end if
    '
    '
    ojn=jn
    w1=""
    w2=""
    w3=ow
    nst+=1
    opo=op
    ofpu=fpu : fpu=0
    c=typk 'cast-type if any
    jn=0
    b=bvg
    a=asgm
    asgm=0
    typ=cpuw
    wp=procedures(s,i,wr)
    asgm=a
    '
    if ert then goto exitexpr
    skiplspace(s,i)
    fpu=ofpu
    op=opo
    jn=ojn
    bvg=b
    nst-=1
    if fpu>0 then
      if (op<2)and(typa1=0)and(typ<&h40)and(isxn) then fpu=0 : typc=cpuw
    end if        
    if (typ=0)or(indt<>0) then typc=cpuw : goto doneprocs 'NOTIONAL RETURN TYPE
    '
    '
    'TRANSFER FLOAT FROM SIMD TO FPU
    '-------------------------------
    '
    'FPU TYPE &H40 IS EXCLUDED
    'APPLIES ONLY TO MS64 CALLING CONVENTION
    '
    if (cpuw=8)and(cco=2) then
      if (typ>&h60)and(typ<=&h68) then
        wp+=simdtofpu(typ)
      end if
    end if
    '
    if typ=&h40 then
      typ=&h6a 'TREAT FPU TYPE AS EXTENDED PRECISION
    elseif (cpuw=4)and(typ>&h40)and(typ<&h4f) then
      w2+=fpuquad
    end if
    '
    if c then
      typ=c 'USE CAST FOR THE RETURN TYPE
    end if
    '
    typa=typ
    '
    '==============
    'STRING OPERAND
    '==============
    '
    'CONVERT NUMERIC ACCUM TO STRING
    '===============================
    '
    if isstr(typ) then
      if (typc>0)and(typc<&h80) then
        if op>1 then
          '
          'NUMBER ACCUM FOLLOWED BY RETURNED STRING
          '
          if jn then
            a=43
          else
            a=1
          end if
          w1=cvtai(typc,&hc1)+logas()+operi(a,&hc1,cpua) 'STRING ACCUM
        end if
        typc=&hc1 'NOW STRING ACCUMULATOR
      end if
    end if
    '
    if isdstr(typ) then
      '
      '
      'BSTRING LOADING / CONCATENATION
      '===============================
      '
      a=typ and 31
      b=typa1 and 31
      c=isxn
      d=0
      typ=upgradelen(&hc1,a)
      typa=typ
      if op=0 then op=1
      '
      '
      if (c<>0)and(jn=0)and(op<2) then
        '
        if (isdstr(typa1)<>0)and(a=b) then
          '
          d=1 'ASSIGN TO VARIABLE DIRECTLY
          '
        elseif (typa1=0)and(parx>0) then
          '
          d=1
          w2=logas() 'FUNCTION PARAM DIRECT (ALSO LOG FOR DELETION)
          '
        end if
        '
      end if
      '
      if d=0 then
        w2=logas()+operi(op,typ,"") 'LOG FOR DELETION AND USE CONCATENATE
      end if
      '
      typc=typa
      '
      if (op<2)and(cnd) then usx=typ
      goto doneprocs
      '
    elseif iszstr(typ) then 'ZSTRING (assume is PTR)
      '
      w2=operi(op,typ,cpua)
      '
      if typc<typa then typc=typa 'itr wide string check
      '
      if (op<2)and(cnd) then usx=typ
      goto doneprocs
      '
    end if
    '
    if op<2 then
      if typc=0 then
        typc=typa 'NO CONVERSION REQUIRED
        if typc<&h40 then
          wp+=cvtai(typa,cpuw)
          typc=cpuw : typa=cpuw
        end if
      end if
    end if
    '
    if noto then
      wp+=operi(11,typ,"")
      noto=0 'NOT
    end if
    '
    '
    'OTHER PRIMITIVES
    '================
    '
    if typc<htyp then
      '
      a=typa
      '
      '
      '
      if (isstr(typc)<>0)and(a>0)and(a<&ha0) then
        '
        'STRING ACCUM BUT NUMERIC RETURNED FROM PROC
        '===========================================
        '
        'SUPPORT NUMERIC EXPRESSION
        typc=typa
        op=1
        goto doneprocs
        '
      else
        '
        if typc>typa then
          w2=cvtai(typa,typc) : typa=typc  'UPGRADE OPERAND
        end if
        '
      end if
      '
      if op>1 then
        '
        'NUMERIC ACCUM
        '=============
        '
        if typa>typc then
          w1=cvtai(typc,typa) : typc=typa  'UPGRADE ACCUMULATOR BEFORE PROCEDURE
        end if
        '
        w5=tmpvar() : w6=tmpvar()
        w1+=operi(2,typc,w5)
        w2+=operi(2,typa,w6)+operi(1,typa,w5)+operi(op,typa,w6)
        '
      else 'op<=1
        typc=typa
      end if
      '
    end if
    '
    '---------
    doneprocs:
    '---------
    '
    if ert then goto exitexpr
    wt+=w1+wp+w2
    uex=1024 'SIGNAL TO USE FULL EXPRESSION
    skiplspace(s,i)
    goto nextops
    '
  end if
  '
  '
  '==============
  'O2 INLINE CODE
  '==============
  '
  if wr="o2" then
    wt+=wr+" "+captureblock(s,i,"")+cr
    typc=typa1
    goto xassigns
  end if
  '
  '
  '
  'INTRINSIC MACROS
  '
  '===========
  floatmacros:
  '===========
  '
  if mc=-17 then
    uex=1024 'SIGNAL TO USE FULL EXPRESSION
    b=ascn 'check for bracket later
    'w2=enc("fm "+hexci(mp)+" "+wr)
    '
    if wr="pi" then m=0 else m=1
    '
    if typc<&h40 then
      if op>1 then wt+=cvtai(typc,&h68) 'UPGRADE ACCUM
      typc=&h68
    end if
    '
    typ=&h68 : typa=typ
    '
    'PI and any other FPU consts
    if (m=0)and(b<>lbr) then
      wt+=macso(mp,1)+cr
      if op>1 then
        wt+=operi(op,typ,chr(127)) 'NORMAL MATH OP
      end if
      goto nextops
    end if
    if b<>lbr then
      w1=captsr(s,i)+")" 'WITH COMMAS
      inserts(s,w1,i)
      b=lbr : i-=1
    end if
    '
    'WITH BRACKETS 'sin(a)  sin(a*b)  atan(y,x)
    '
    i+=1
    if fpu>=0 then
      fpu+=1   ' FPU NESTING FROM CPU MODE
    elseif fpu<0  then
      fpu=1024 ' CPU MODE SWITCH TO FPU MODE
    end if
    n=1
    c=-mp   'FPU NESTING
    stk.g=0 'NO TEMP VAR, NO PRECALC
    goto nestexp
  end if
  '
  '
  '========
  nestpush:
  '========
  '
  '
  '  #
  ' #  '=================
  ' #  NESTED EXPRESSIONS
  ' #  '=================
  '  #
  '
  if ascw=lbr then
    '
    'IGNOTE EMPTY BRACKETS
    if ascn=rbr then
      i+=1
      goto oploop
    end if
    '
    'NESTED STRING EXPRESSIONS
    if isstr(typc) then
      'ignore precedence brackets around string expression: (a+b)&(c+d)
      b=swd
      m=b 
      capture(s,m,b,a)
      mid(s,b-1)=" " 'strip right bracket
      goto oploop
    end if
    c=0
    n=1
    if (typc<htyp) then
      if (fpu<=0)or(typc<&h40) then
        w1=tmpvar() : w1="" : a=me-1
        if op>1 then
          wtn(nst)=wt  'HOLD CURRENT CODE STREAM
          wt=""        'START FRESH CODE STREAM
          stk.g=a      'TEMP VAR RECORD INDEX
        else
          stk.g=-a     'TO LOAD NESTED RESULT
        end if
      end if
    end if
    goto nestexp 'PREPARE FOR NESTED EXPRESSION
  end if
  '
  '
  '        #
  ' ####  #  ======
  ' #  #  #  ARRAYS
  ' ####  #  ======
  '        #
  '
  '
  if (ascn=lbr)and(ascw<>rbr) then
    '
    'itr submembers this.c[m].a[n] etc
    a=instr(ow,".") 'IMPLICIT THIS HAS BEEN MADE EXPLICIT PRIOR
    if a then
      wc(nst)=mid(ow,a+1) 'MEMBER
      po(nst)=woff
    else
      wc(nst)=""
      po(nst)=0
    end if
    w1="" : c=mp : i+=1 : n=1 ' flag array params
    '
    if c=0 then ert=32 : ers="Unidentified array or procedure" : goto exitexpr
    '
    '
    '======
    'ARRAYS
    '======
    '
    pid=0 'SIB / postincdec
    stk.g=0
    '
    'ARRAY ADDRESS
    '
    ainv=ind
    aint=indt 'ARRAY OF POINTERS
    '
    ains=""
    '
    if ainv then
      if aint=0 then
        if iszstr(typc) then aint=1 'char**C
      end if
    end if
    '
    if aint then
      '
      'SPLIT INDIRECTION PROCEDURE
      '
      ains=splitderef(ainv-aint) 'effectively splitting wpfx
      '
      'ARRAY FOR ASSIGNMENT OPERAND (OP=2)
      '
      if arf=2 then
        if (iszstr(typa)<>0) then
          addrtrim(ains)
        end if
      end if
      xmode=2 'FULL PRECALC INDEX
    end if  'aint
    '
    wra=wu     'ARRAY VARIABLE
    wpfxa=wpfx   'ARRAY BASE ADDRESS RESOLUTION
    wt+=wpfx+"lea "+qesi+cm+wra+cr 'INDEX ACCUMULATOR
    '
  end if ' ascn=lbr
  '
  'ALL NESTINGS
  '============
  '
  '=======
  nestexp:
  '=======
  '
  '
  if n then
    stk.a=op   'OPERATOR
    stk.b=typc 'ACCUMULATOR TYPE
    stk.c=c    'ENTITY CODE
    stk.d=cp   'COMPARATOR
    stk.e=tp   'COMPARE TYPE
    stk.f=ind  'INDIRECTION LEVEL
    stk.h=omp  'LAST OBJECT
    stk.i=noto 'NOT' FLAG
    stk.k=typa 'OPERAND TYPE
    '
    if elsize then
      stk.j=elsize 'ELEMENT SIZE
    else
      stk.j=maco(c,1) 'VAR SIZE
    end if
    '
    if aint>0 then
      stk.j=cpuw
    end if
    '
    if nst>=99 then ers="too many () nestings " : ert=300 : goto xassigns
    st(nst)=stk
    nst+=1
    '
    '
    if typc=cpuw then
      typc=0 'TYPC TAKES ON TYPA IDENTITY
    end if
    '
    if c>0 then 'ARRAY
      typc=0 'higher types do not arrive here
    elseif c<0 then 'FLOAT MACRO
      typc=&h68
    end if
    '
    cp=0 : tp=0 : noto=0 : op=1
    goto oploop
    '
  end if
  '
  '
  '=======
  nestpop:
  '=======
  '
  '
  '
  ' #
  '  #  ==================================
  '  #  END OF NESTING OR ARRAY EXPRESSION
  '  #  ==================================
  ' #
  '
  ' NESTING STACK:
  '--------------------------------------------------------
  ' A  op   operation (-1 non) (0 or 1 mov)
  ' B  typc accumulator type
  ' C  c    array attributes locator / -ve intrinsics flag
  ' D  cp   conditional (flag) code
  ' E  tp   conditional L accummulator type
  ' F  ind  indirection level
  ' G  tmp   temp variable attributes locator
  ' H  omp  last object   
  ' I  noto 'not' flag
  ' J  elsize or varsize
  ' K  typa array var type
  '--------------------------------------------------------
  '
  if ascw=rbr then
    '
    'MAKE COMPARISON IF CP INSIDE BRACKETS
    '-------------------------------------
    '
    if cp then
      if isstr(typc) then
        '
        'STRINGS
        a=typc and 31
        typc=&hc0+a
        '
        'STRING OPTIMIZATION
        if (op<2)and((typc and 31)=1)and((tp and 31)=1) then
          if usx then
            if isdstr(usx) then wt+=logas
          end if
        else
          wt+=operi(96,typc,"")+logas() 'CONCAT LOGICAL RESULT AFTER STRING COMPARE
        end if
        usx=0
        '
      elseif typc<htyp then 'NON STRING PRIMITIVES
        '
        wt+=cvtai(typc,tp) : typc=tp 'convert to left side type 'itr
        '
      end if
      '
      if typc<htyp then
        'PRIMITIVES
        wt+=operi(cp,tp,w4)
      end if
      typc=cpuw 'sys type for logical result
    end if 'cp
    '
    'CHECK FOR EXCESS RIGHT BRACKETS
    '-------------------------------
    '
    if nst<1 then
      '
      'CHECK FOR RECURSIVE ASSIGNMENT BEFORE LOGGING AN ERROR
      '
      ers="Too many right param brackets" : ert=300
      goto xassigns
      '
    end if
    '
    '
    'CLOSE THE NESTING  (ACCUM-->OPERAND : POP ACCUM WITH OPERATOR / ARRAY BASE / FUNCTION
    '-----------------
    '
    typa=typc
    '
    ocp=cp
    nst-=1
    stk=st(nst)
    typc=stk.b
    op=stk.a
    c=stk.c
    cp=stk.d
    tp=stk.e
    ind=stk.f
    noto=stk.i
    '
    '
    'DETERMINE OPERAND TYPE (whether array or result of nested expression)
    '
    if c>0 then
      typ=stk.k : typa=typ
    else
      typ=typa 'same as typc
    end if
    '
    if typc=0 then typc=typ
    '
    '
    '=====================
    'DOT MEMBERS OF ARRAYS
    '=====================
    '
    if ascn=46 then
      '
      if asc(s,i+1)=62 then '.>' derived from '->'
        i+=1
        'itr ind?
      end if
      '
      i+=1
      w1=tword(s,i)
      '
      if len(wc(nst)) then
        w1=wc(nst)+"."+w1
      end if
      wc(nst)=w1
      '
      'IDENTIFY THE MEMBER
      '
      '
      '
      'READ THE MEMBER ATTRIBUTES
      '
      ow=macso(stk.c,0)+"."+w1 'VAR NAME EXCLUDING ARRAY SPEC
      'SUPPORTING DIRECT & INDIRECT MEMBERS
      a=-1
      mp=stk.c
      findmemb(w1,memba,a,m)
      '
      if a=0 then
        ers="Array member not found" : ert=500 : exit function
      end if
      '
      if varf=3 then
        'INDIRECT MEMBERS
        xmode=2 'FLAG FULL INDEX CALC
        memba=memreg(qedi,woff) 'OFFSET ADDED LAST
        a=instr(wpfx,cr)
        if a then
          membb=mid(wpfx,a+2) : wpfx="" 'TRIM OFF BASE VARIABLE
        end if
        woff=0
      else
        memba=""
      end if
      '
      m=woff        'OFFSET
      stk.j=elsize  'LENGTH
      stk.k=typ     'TYPE
      if indt then stk.j=cpuw
      v=varf        'OBJECT ATTRIBUTES (varf code)
      tye=typ
      typa=typ
      if op<2 then
        typc=typa
      end if
      '
      'ADD ELEMENT RELATIVE OFFSET TO THE OVERALL ARRAY OFFSET
      '
      skiplspace(s,i)
      '
      if ascn=91 then fixsqbr(s,i)
      if stk.j>0 then
        if v<=8 then  'EXCLUDE METHOD OFFSETS (this base)
          a=m-po(nst) 'RELATIVE MEMBER OFFSET
          if a then 'EXCLUDE OFFSET 0
            xoffs+=a 'DIRECT OFFSET ADJUSTMENT
            wt+="add "+qesi+cm+str(a)+cr
          end if
        end if
      end if
      '
      po(nst)=m
      '
      '=====================
      'SUBARRAYS   a(x).b(y)
      '=====================
      '
      'IS THERE A SUBARRAY
      '
      if varf<8 then
        '
        if ascn=91 then fixsqbr(s,i)
        '
        if ascn=lbr then
          '
          'PLACE THE AMMENDED DESCRIPTION
          '
          st(nst)=stk
          '
          '
          '
          'NEST IMPLICITLY
          '---------------------
          '
          nst+=1
          '
          'SKIP BRACKET
          '------------
          '
          i+=1 : skiplspace(s,i)
          '
          'SET ACCUM TO INTEGER TYPE WITH OP=LOAD
          '--------------------------------------
          '
          typc=cpuw : op=1
          '
          'RESUME EXPRESSION LOOP DIRECTLCY
          '--------------------------------
          '
          goto oploop
          '
        end if
        '
      end if 'SUBARRAYS
      '
      '
      'RESOLVED FINAL OFFSET
      '---------------------
      '
    end if 'DOT
    '
    '
    '=============
    'ARRAY ACCESS
    '=============
    '
    if c>0 then
      '
      if typa1>=htyp then 'HIGHER TYPES
        if tye then
          typa1=tye 'CAST AS ELEMENT TYPE
        end if
      end if
      '
      '
      'GET OPERAND
      '
      if (xmode>=0)or(aint<>0) then 'NON DIRECT OFFSETS
        if xmode=3 then
          wr=memregadj(wra,xoffs)
          wt=xcalc  'SIB ENCODED OFFSET
        else 'CALCULATED OFFSET
          w3=tmpvar()
          epfx+=wt+"mov "+w3+cm+qesi+cr
          wt=medi+w3+cr+ains
          xmode=0 'no need to push accum
          ains=""
          if len(memba) then
            if len(membb) then
              wt+=membb
            else
              wt+=medi+memba+cr
            end if
            memba=""
            membb=""
          end if
          wr=pedi
        end if
      else 'xmode=-1 'DIRECT OFFSET
        wr=memregadj(wra,xoffs)
        wt=wpfxa
      end if
      '
      'xoffs=0
      'xmode=0
      'aint=0
      '
      goto nassignt 'ARRAY RESOLUTION
      '
    end if 'ARRAYS c>0
    '
    '
    '----------
    'INTRINSICS
    '==========
    '
    if c<0 then
      b=&h68 'ALWAYS FLOAT
      if isstr(typa) then
        wt+=operi(96,typa,"")+logas() 'CONCAT AND LOG
      end if
      wt+=cvtai(typa,b)+expandmac(-c) : typa=b 'TYPE CONVERSION + INTRINSIC
      if ert then exit function
      '
      if isstr(typc) then 'string accum
        wt+=cvtai(typa,typc)
        if (op>1)or(typa1=0) then
          wt+=logas() 'LOG AS TEMP STRING
        end if
        wt+=operi(op,typc,"")
        fpu=0
        goto postops
      end if
    end if 'INTRINSICS c<0
    '
    '--------------------------------------
    'BOTH NESTED EXPRESSIONS AND INTRINSICS
    '======================================
    '
    'BITWISE NOT()
    '
    if noto then
      'if (op<2)or(typa>=&h40) then w1="" else w1=pesp
      w1=""
      wt+=operi(11,typa,w1)
      noto=0 'NOT
    end if
    '
    '
    'CHECK / TRANSFER ACCUM FROM FPU TO CPU OR VAL TO STRING
    '
    if fpu<=-1 then
      if isfpu(typc) then wt+=cvtai(typc,cpuw) : typc=cpuw : typa=cpuw
    end if
    '
    '
    'INDIRECTION *(A+B)
    '-----------
    '
    if ind then
      if c=0 then
        for a=1 to ind
          wt+=operi(1,cpuw,peax) 'DEREFERENCE
        next
      end if
    end if
    '
    'STORE RESULT IN TEMP VAR (EXCEPT FOR STRINGS)
    '
    'CHECK FOR END OF NESTED EXPRESSION
    'LOOKAHEAD FOR NEXT OPERATOR (FOR LAZY JUMP)
    if nisxn then
      d=identop(s,i,0)
      if op then ctop+=1
      skiplspace(s,i)
    else
      d=0
    end if
    '
    if (nst=0)and(ocp)and(typc<&h40) then laz=lazyjump(d) else laz=""
    '
    if stk.g>0 then
      '
      'STORE RESULT IN TEMP VAR AND REORGANISE CODE
      '
      w1=""
      w2=""
      b=typc
      w3=macso(stk.g,1)
      '
      if isfloat(typa) then typa=&h68
      if isfloat(typc) then typc=&h68
      '
      if typa>typc then
        w2=cvtai(typc,typa) 'UPGRADE ACCUM BEFORE
        b=typa
      elseif typc>typa then
        w1=cvtai(typa,typc) 'UPGRADE OPERAND
      end if
      '
      'TO SUPPORT NESTED EXPRESSIONS
      '
      epfx+=wt+w1+laz  'STORE NEST RESULT IN TEMP VAR (IN ADVANCE)
      if hix=0 then epfx+=operi(2,b,w3) else b=maco(stk.g,5)
      wt=wtn(nst)+w2+operi(op,b,w3) 'OPERATE ON TEMP VAR
      wtn(nst)=""
      typc=b
      skiplspace(s,i)
      '
    elseif stk.g<0 then
      'LOAD NESTED RESULT
      'USE TEMP VAR IF FURTHER OPS FOLLOW
      if d then 'FURTHER OPS
        if isstr(typc)=0 then 'EXCLUDE STRINGS
          b=typc
          if isfloat(typc) then
            if ocp then 'NESTED COMPARE
              b=cpuw
            end if
          end if
          w3=macso(-stk.g,1)
          epfx+=wt+laz
          if typa1<htyp then
            epfx+=operi(2,b,w3) : wt=operi(1,b,w3)
          else
            b=maco(-stk.g,5) : epfx+=operi(1,b,w3)
          end if
          w3=""
        end if
      end if 'd
    elseif (fpu>0)and(op>1) then
      wt+=operi(op,typc,chr(127)) 'FPU OPERATIONS
    end if
    ocp=0
    if op<=1 then typc=typa
    stk.g=0
    hix=0
    '
    '
    '=======
    postops:
    '=======
    '
    'INTRINSICS
    '
    if c<0 then
      if fpu<0 then
        fpu+=1    'REDUCE NESTING OF CPU INSTRINICS
      elseif fpu=1024 then
        fpu=-1 'REVERT TO CPU MODE
      elseif fpu>0 then
        fpu-=1    'REDUCE NESTING OF FPU INTRINSICS
      end if
    end if
    '
    if isstr(typc) then op=qp 'CAT CONTINUITY
    goto nextops
    '
  end if ' ) RBR
  '
  ' #
  '  #   ###
  '  #   ### END
  '  #   ###
  ' #
  '
  '==========================
  cvtop: 'CONVERT AND OPERATE
  '==========================
  '
  if op<=2 then
    if (cnd=0)and(ascn=61)and(asc(s,i+1)<>61) then
      goto nextops 'ASSIGNMENT (LEFT SIDE OF STATEMENT)
    end if
  end if
  '
  '
  w1="" : b=0
  '
  'TO STRING TYPE
  '==============
  '
  if isstr(typa) then
    '
    b=isq(ascw)
    '
    '
    if asgm then
      if op<2 then
        typc=typa
        if typc<&hc0 then typc+=32 'possible '<=' multiassign
      end if
    end if
    '
    'AUTOCONVERT ACCUM NUMBERS TO STRING
    '
    if (typc<&ha0) then
      if op>1 then
        wt+=numtostr(typa,typc) 'CONVERT NUM ACCUM TO STRING ACCUM
        typc=typa
     else 'OP<=1
        typc=typa
      end if
    end if
    '
    '
    if isstr(typc) then
      typc=upgradelen(typc,typa) 'UPGRADE STRING WIDTH
      if b=0 then goto ncvto 
    end if
    '
    if b then
      typc=typa
      wpfx=enc("qu "+wr)
      w1=wpfx+operi(op,typa,"") 'SGL
      goto xcvto
    end if
    '
  end if
  '
  'TO NUMERIC TYPE
  '===============
  '
  if typc<&h80 then
    w1+=wpfx+numoperation(wr,typa,typc) 'CAN UPGRADE OPERAND OR ACCUM TYPE
    goto xcvto 
  end if
  '
  '
  '=====
  ncvto:
  '=====
  '
  w1+=wpfx+operi(op,typa,wr)
  
  '
  'DONE OPERATION
  '
  '=====
  xcvto:
  '=====
  '
  if fpu=-1 then w1+=cvtai(typc,cpuw) : typc=cpuw 'CONVERT TO CPU
  '
  '
  wt+=w1
  '
  '
  '============================
  ' 
  '      ###           ###
  '      ###              ##
  '  ###########         ##
  '  ###########       ##
  '      ###           ##
  '      ###           ##
  '
  '============================
  '
  '
  nextops:
  '=======
  '
  qp=op
  '
  if clbr then
    if nst=0 then
      if ascw=rbr then
        goto xassigns 'IF (A==B) ++C;
      end if
    end if
  end if
  '
  'skiplspace(s,i)
  '
  'POST ++/-- postincdec
  '=====================
  '
  if (ascn=43)or(ascn=45) then
    a=asc(s,i+1)
    if a=ascn then
      if a=43 then pid=12 else pid=13
      wt+=wpfx+operi(pid,typ,wr)
      i+=2 : skiplspace(s,i)
    end if
  end if
  '
  '
  '
  'CHECK FOR ASSIGNMENT OPERATOR
  '=============================
  '
  a=0
  b=asc(s,i+1)
  '
  if ascn=58 then
    if b=61 then i+=2 : a=2          ' := ASSIGN/COMPARE
  elseif ascn=61 then
    if b=61 then
      '                              ' == COMPARE ONLY
    elseif casg then
      i+=1 : a=2                     ' =  ASSIGN/COMPARE WHEN IN C SYNTAX MODE #assign
    else
      if cnd=0 then a=2 : i+=1       ' =  ASSIGN/COMPARE WHEN NOT CONDITIONAL
    end if
  end if

  if a then
    '
    '
    'EXAMPLE:
    '
    '  IF (A:=B+C) THEN ...
    '  IF (A:=F(B)) THEN ...
    '  A=B
    '  A(42)=B
    '
    'THESE ARE EVALUATED RECURSIVELY
    '
    if asxp=1 then
      wt=""
      w1="'ASSIGN:"+cr
    else
      'MULTISTORE: store but leave floats on fpu stack
      w1="'STORE:"+cr
      a=14
    end if
    w1+=wpfx+operi(a,typa,wr)
    'ASSIGNMENT PROCEDURE FOR DYNAMIC STRINGS
    if (typa>=&he0)and(typa<&h100) then
      w2=mid(macso(mp,1),3,3)
      if w2="bp-" then a=asstrla else a=asstrga 'LOCAL GC / GLOBAL GC
      w1+=rtlo(a)
    end if
    '
    op=1
    'itr upgrade accum?
    if (nst<>0) then typc=st(nst-1).b
    'wt+="'EVALUATE:"+cr
    w2=express(s,i,typa) 'RECURSIVE
    wt+=w2+w1
    if isstr(typa) then
      if typa>&he0 then typa-=32 'USE DIRECT BSTR &hC1..
      'wt+=operi(1,typa,qeax) 'RELOAD CATBUF
    else 'not dynamic strings
      if typc<>typa then
        wt+=cvtai(typa,typc)
        typa=typc
      end if
    end if
    '
    goto nextops
    '
  end if
  '
  '
  '
  'IS END OF EXPRESSION?
  '---------------------
  
  '   ###
  '  #####
  '   ####
  '     ##
  '    ##
  '   #
  '
  if isxn then
    '
    '  
    '                                                ##          ##
    '                                              ##              ##
    '----------------------------------------    ##     ########     ##
    'CHECK IF PART OF MULTIPLE ASSIGNMENT  <=  ##                      ##
    '========================================    ##     ########     ##
    '                                              ##              ##
    '                                                ##          ##
    multiassigns:
    '============
    '
    'primitive elements only
    'but assignment entity may be any type (including classes)
    '
    static as sys amc,ami,amo, htf 'FOR ARRAYS OF MEMBERS
    if asgm then
      '
      op or=uex 'uex procedures flag, prevents direct variable assign
      '
      if nst=0 then
        if typa1<htyp then 'ASSIGNIN TO PRIMITIVE TYPES
          typ=typa1
          a=typa1 and 31
          if typa1>&ha0 then a=cpuw
          asgi=a 'MAIN STRIDE
          '
        elseif typa1=typc then
          '
          asgi=maco(typa1-htyp,1) 'MAIN STRIDE
          asgo=asgj
          '
        else 'ASSIGNING TO HIGHER TYPES
          '
          'TRAVERSE ELEMENTS OF TYPE OR CLASS
          b=0 'LOOP ITERATION FLAG
          asgi=maco(typa1-htyp,1) 'MAIN STRIDE
          '
          'nextmember
          do
            '
            if asgk<=1 then
              asgk=1                'SET START OF STRUCTURE
              asgn=-1               'RESET STRUCTURE OFFSET TRACKER
            end if
            '
            'GET NEXT ELEMENT
            '
            if amc then             'ARRAY OF ELEMENTS
              amc-=1                'COUNT OFF ARRAY ELEMENTS
              amo+=ami              'STRIDE ARRAY
              exit do               'READY FOR DATA TRANSFER
            elseif typc>=htyp then
              htf=1
              do
                nextmemb(asgs,asgk,htf)    'NEXT SUBMEMBER HEADER
                if asgk=0 then exit do   'NO MORE SUBMEMBERS
                if typ=typc then exit do 'MATCHING TYPE
              loop
              amo=0
            else 'typc<htyp
              htf=0
              nextmemb(asgs,asgk,htf)
              amo=0                       'CLEAR ANY PRIOR MEMBER ARRAY OFFSET
            end if
            '
            if asgk then                  'NEXT ELEMENT IS LOCATED
              while woff<asgn            'ONLY FIRST MEMBER OF A UNION IS USED
                nextmemb(asgs,asgk,htf)     'SO TRY FOR THE FIRST ELEMENT OUTSIDE THE UNION
                if asgk=0 then exit while
              wend
            end if
            '
            if asgk then
              asgn=woff+elsize   'RECORD NEXT OFFSET IN STRUCTURE
              if aml>1 then      'ARRAY OF MEMBERS DETECTED
                amc=aml-1        'SET ARRAY ELEMENT DOWN COUNTER
                ami=elsize       'SET STRIDE
              end if
              exit do            'OKAY, READY FOR DATA TRANSFER
            end if
            '
            if b then 'ALREADY TRIED TO LOCATE ONCE
              ers="Element not located "+macso(typa1-htyp,0)
              ert=202
              goto nassignt 'ABANDON EXPRESSION
            end if
            '
            b+=1       'INCREMENT LOOP ITERATION FLAG
            asgj+=asgi 'NEXT ITEM: GOTO START OF STRUCTURE
            '
          loop
          '
          asgo=woff+asgj+amo 'MEMBER OFFSET + MAIN ARRAY OFFSET + MEMBER ARRAY OFFSET
          '
        end if
        '
        'HIGHER (COMPOUND) MEMBERS ASSIGN
        '
        if typc>=htyp then
          if typa1<htyp then
            asgo=asgj 'ARRAY OFFSET WHEN ASSIGNING TO PRIMITIVE ARRAY
          end if
          'COPY HIGHER MEMBER
          rps=32
          a=maco(typc-htyp,1)
          hiex+="copy @"+osg+"+"+str(asgo)+cm+"@"+owa+cm+str(a)+cr 'EXPRESSION TO BE REPROCESSED
          if typa1<htyp then
            asgi=a 'STRIDE USING ARRAY OFFSET ASGJ
          end if
          goto nextmulti 'FWD
        end if
        '
        'GENERAL (PRIMITIVE) MEMBERS ASSIGN
        '
        'convert to accum required type
        '
        w1=cvtai(typc,typ)
        if (typ<&h40)and(typc<&h40) then
          a=typ  and 31
          b=typc and 31
          if a<=b then w1=""
        end if
        '
        if (op>1)or(len(w1)+len(wpfx)>0)or(pargl<>0) then
          w1+=reloadaddr
        end if
        '
        'STRING CONCATENATION
        '
        if (jn>0)and(isdstr(typ)<>0) then
          wt+=operi(96,typ,"")
        end if
        '
        a=0
        '
        if nan=0 then
          if (op<2)and(typc=cpuw)and(w1="") then a=1
        end if
        '
        ' multiassigna(wt,w1,wr,a)
        if a then
          a=instrevn(len(wt)-2,wt,cr)
          if a then
            w1+=left(wt,a+1)
          else
            w1=wt
          end if
          wt=w1+"mov "+identypes(typ)+memreg(qedi,asgo)+cm+wr+cr 'INTEGER NUMBERS
        else
          wt+=w1+operi(2,typ,memreg(qedi,asgo))
          if (typ>=&he0)and(typ<&h100) then
            if asgl then a=asstrla else a=asstrga
            wt+=rtlo(a) 'STRING ASSIGNMENT WITH GARBAGE COLLECTION
          end if
        end if
        '
        if typ>=&h80 then
          pargl=1 'ENSURE FUTURE EDI RELOAD AFTER ASSIGNING STRINGS
        else
          pargl=0
        end if
        '
        nextmulti:
        '=========
        '
        if (typa1<htyp)or(typa1=typc) then
          asgj+=asgi
          asgo=asgj 'STRIDE FOR NEXT ELEMENT (BUT HIGHER TYPES RECALCULATE ASGO)
        end if
        '
        skiplspace(s,i)
        '
        'CHECK FOR CLOSING INNER } ASGB
        '
        while asgm>0
          nextinstruct(s,i)
          if ascn=asgb then
            i+=1 : asgm-=1
            if (asgm=1)and(typa1>=htyp)and(typa1<>typc) then
              asgj+=asgi : asgk=0 'NEXT ELEMENT IN MAIN ARRAY
              asgo=asgj 'FOR FUTURE PRIMITIVE ASSIGNMENTS
            end if
          else 'ascn<>asgb
            exit while
          end if 
        wend
        '
        'SET ACCUM TYPE FOR NEXT ASSIGNMENT
        '
        if typ>&ha0 then
          typc=0 'fresh start for strings and above
        else 
          typc=typ 'anticipating next el type
        end if
        '
        'CHECK FOR CLOSING OUTER } OR )
        '
        uex=0
        '
        '
        'CHECK FOR NEXT ELEMENT
        '
        skiplspace(s,i)
        '
        if (ascn=44)and(asgm>0) then
          i+=1 : nextinstruct(s,i) : op=1
          goto oploop
        end if
        '
        'FINISH MULTI-ASSIGN OR NEXT
        '
        amc=0 : op=0 : wr="" : asgm=0
        if vew>0 then wt+=";END MULTIASSIGN"+cr
        goto nassignt
        '
      end if 'nest nst
    end if 'asgm
    '
    'CHECK IF NOT NESTED
    '===================
    '
    if nsl=nst then
      goto xassigns
    end if
    '
    'CHECK IF PART OF AN ARRAY INDEX
    '===============================
    '
    if nst then
      a=0 : c=st(nst-1).c
      '
      'EXCLUDE NON-ARRRAY
      '
      if c<1 then
        goto xdimix  'EITHER INTRINSIC OR NESTED EXPRESSION
      end if
      '
      d=nst-1
      a=st(d).j 'ELEMENT SIZE
      '
      if a then
        if uex then
          ert=509 : ers="index expression complexity [..]" : nst=0 : goto exitexpr
        end if
        if (nan=0)and(op<=1) then
          '
          'ADD OFFSET DIRECTLY TO ADDRESS
          '
          b=a*(dv-ixb)
          xoffs+=b 'ADD TO PRIOR OFFSETS
          if b then wt+="add "+qesi+cm+str(b)+cr 'PRE-EMPTIVE CODE for adding to index
          if xmode=0 then
            xmode=-1
          end if
        else
          d=0 : m=0
          if (xmode<=0)and(typa<&h40)and(aint=0) then
            select case a
            case 1    : d=-1
            case 2    : d=-1
            case 4    : d=-1
            case 8    : d=-1
            case 16   : d=1
            case 32   : d=2
            case 64   : d=3
            case 128  : d=4
            case 256  : d=5
            case 3 to 127 : d=-2
            case 129 to &h7fffffff : d=-3
            end select
          end if
          m=d
          if op>1 then d=0
          '
          'INDEXER AND IMMEDIATE OFFSET
          if (op=43)or(op=45) then
            if (m=-1)or(m>0) then
              if (ctop=1)and(nan=0) then
                if op=43 then v=1 else v=-1
                xoffs=xoffs+wval(wr)*a*v
                d=m : m=999
              end if
            end if
          end if
          '
          if d then
            '
            'MAY USE A SIB ENCODING ONCE ONLY
            '
            w2="and "+qecx+cm
            select case typa and 31
            case cpuw : w2=""
            case 4    : w1="ecx" : w2+="0xffffffff"+cr
            case 2    : w1="cx"  : w2+="0xffff"+cr
            case 1    : w1="cl"  : w2+="0xff"+cr
            end select
            'INDEXER AND IMMEDIATE OFFSET
            if m=999 then
              f=instr(1,wt,qesi)
              f=instr(f,wt,cr)
              w4=mid(wt,f+2) 'exclude initial qesi
              f=instrevn(-1,w4,"|op 1 ") 'mov
              w3=left(w4,f-1) 'extract pre-address resolving code, if any
              'extract first operand of index
              m=instr(f,w4,cr)
              f+=8
              wr=mid(w4,f,m-f) 'indexer
              xcalc=w3 'pre-address of indexer
            else
              xcalc=wpfx
            end if
            if len(w2) then
              xcalc+="mov "+w1+cm+wr+cr+w2 'mask upper bits
              w1=qecx
            else
              w1=wr
            end if
            xcalc+="mov "+qesi+cm+w1+cr
            '
            '
            xoffs=xoffs+a*(-ixb) 'ADD TO PRIOR OFFSETS
            '
            if pid then xcalc+=operi(pid,typ,wr) 'posincdec
            b=a
            if d>0 then
              xcalc+="shl "+qesi+cm+str(d)+cr
              b=8
            elseif d=-2 then
              xcalc+="imul "+qesi+cm+qesi+cm+str(a)+cr
              b=1
            elseif d=-3 then
              xcalc+="mov "+qecx+cm+str(a)+cr + _
                   "imul "+qesi+cm+qecx+cr
              b=1
            end if
            xcalc+=wpfxa
            '
            'wra=SIBencode(xcalc,wra,b)
            if b>0 then w1="*"+str(b) else w1=""
            if isn(asc(wra,2)) then
              xcalc+="xor "+qedi+cm+qedi+cr
              wra="["+qedi+"+"+qesi+w1+"+"+mid(wra,2) ' [n] absolute address
            else
              wra=left(wra,4)+"+"+qesi+w1+mid(wra,5)
            end if
            xmode=3
          else 'CALC OFFSET
            xmode=2 'ALWAYS USE FULL ENCODING
          end if
          '
          dimix:
          '=====
          '
          w1=""
          '
          'BASE
          '
          if ixb then
            if ixb=1 then
              w1+=operi(13,cpuw,qeax)     'DEC
            else
              w1+=operi(45,cpuw,str(ixb)) 'SUB
            end if
          end if
          '
          'SCALE
          '
          if a then
            select case a
              case 1    : b=0
              case 2    : b=1
              case 4    : b=2
              case 8    : b=3
              case 16   : b=4
              case else : b=0
            end select
            if b then
              w1+=operi(74,cpuw,str(b)) 'SHIFT LEFT
            elseif a>1 then
              w1+=operi(42,cpuw,str(a)) 'MULTIPLY
            end if
          end if
          '
          wt+=cvtai(typc,cpuw)+w1+"add "+qesi+cm+cpua+cr 'PRE-EMPTIVE
        end if
      end if 'element size
      '
      typc=cpuw ' array index int 'INCREMENT TALLY
      '
      '------
      xdimix:
      '======
      '
      '
      'CHECK FOR FURTHER TERMS
      '
      if ascn=44 then
        if c<0 then
          typc=&h68 'INTRINSIC FLOAT READY FOR NEXT TERM
          op=1 : i+=1 ': skiplspace(s,i)
          goto oploop
        end if
        ers="unexpected comma in array index " : ert=401 : goto exitexpr
      end if
      '
      goto oploop 'CONTINUE
      '
    end if 'NST
    '
    if ascn=rbr then
      goto oploop
    else
      goto xassigns
    end if
    '
  end if 'ISXN() END OF EXPRESSION
  '
  '
  '        ##    ##
  '      ##        ##
  '    ##            ##
  '  ##                ##
  '    ##            ##
  '      ##        ##
  '        ##    ##
  '
  '-----------------------------
  'COMPARATORS = < > <= == >= <>
  '=============================
  '
  if ((ascn>=60)and(ascn<=62))or(ascn=33) then
    '
    b=asc(s,i+1)
    '
    'EXCLUDE BIT SHIFTERS << >>
    '--------------------------
    '
    if ascn=b then
      if (b=60)or(b=62) then goto ncompar
    end if
    '
    if (cnd=1)or(cnd=-1) then
      ctal+=1 'count comparisons used in a conditional expression
    end if
    '
    'DETERMINE COMPARATOR CODE
    '-------------------------
    '
    a=ascn : i+=1
    skiplspace(s,i)
    cp=&h14
    if a=60 then cp=&h1c '<
    if a=62 then cp=&h1f '>
    if b=61 then
      '
      i+=1
      '
      if a=61 then
        cp=&h14 '==
      elseif a=33 then
        cp=&h15 '!=
      elseif a=60 then
        cp=&h1e '<=
      elseif a=62 then
        cp=&h1d '>=
      end if
      '
    end if
    if (a=60)and(b=62) then cp=&h15 : i+=1 ' <>
    skiplspace(s,i)
    '
    if isstr(typc) then
      '
      'COMPARE STRINGS
      '
      'STRING OPTIMIZATION
      if (qp<2)and((typc and 31)=1) then
        'DIRECT LOAD LEFT STRING
        if usx then
          wt=wp
          if isdstr(usx) then wt+=logas()
        else
          nstod=1
          typ=typa
          wt=makestrptrfun(wr) 'OVERWRITE PRIOR CAT CODE
          nstod=0
        end if 'usx
        jn=0
      else
        'CONCAT LEFT STRING
        typc=upgradelen(&hc1,typc)
        wt+=operi(96,typc,"")+_    'CONCATENATE
        logas()                    'MARK AS TEMP FOR DELETION
      end if
      usx=0
    end if
    '
    'IF PRIMITIVE THEN STACK THE LEFT HAND SIDE ACCUM VALUE
    '
    w2=""
    w4=""
    w3=wpfx
    tp=typc
    if tp<&h40 then
      a=asc(wr)
      a=isn(a) or (a=45) 'LEFT SIDE INTEGER LITERALS
      if (a)and(qp<=1) then
        goto stdcompare
      end if
      if (abs(cnd)=1)and(nst=0) then
        a=i
        w1=tword(s,i)
        if (ascw=45)and(isn(ascn)) then
          w1+=tword(s,i) 'NEGATIVE NUMBER
        end if
        if (ascn=lbr)or(ascn=91) then
          capture(s,m,i,0)
          w1+=mid(s,m,i-m) 'GET ARRAY INDEX
        end if
        if isendofexpress(s,i) then 'END OF ATOMIC EXPRESSION
          w2=pword(w1,1)
          if (mc=-31)or((typ=typc)and(mc>=0)) then 'NO CONVERSION OR PROC
            a=0
            if (qp<=1)and((typc and 31)=cpuw)and(mc=-31)and(asc(wr)=91) then
              a=instrevn(-1,wt,"|")
              if a then
                if mid(wt,a+1,2)<>"op" then
                  a=0 'function or conversion returning in eax: cmp eax,32
                end if
              end if
              if a then
                wt=left(wt,a-1)
                w2=identypes(typc)+wr+cm+w2 'EG: cmp word [ebp-8],32
              end if
            end if
            if a=0 then
              w2=qeax+cm+w2    'EG: cmp eax,[ebp-16]
            end if
            d=isendofexpress(s,i)
            if (ctal=1)and(d)and(dts<=0) then
              if cnd=1 then cp xor=1       'OPPOSITE LOGIC
              wt+=wpfx+operi(cp+112,tp,w2) '112 FOR DIRECT COMPARE & JUMP
              ctal=-16                     'FLAG FOR DIRECT JUMP
              op=cp
              typ=tp
              typa=tp
              wr=w2
              wpfx=""
              goto nassignt
            else
              wt+=wpfx+operi(cp,tp,w2)
              op=1
              tp=0
              cp=0
              if d then
                goto nassignt 'END OF EXPRESSION
              else 
                goto oploop 'DONE SIMPLE COMPARE, MORE TO FOLLOW
              end if
            end if 'ctal etc
          end if
        end if
        i=a
      end if
      if (qp<=1)and(w3="")and(wr<>")")and(typ=typc)and(pid=0) then
        a=instrevn(-1,wt,"|")
        if a>=1 then
          if mid(wt,a+1,2)="op" then 'NOT 'go'
            wt=left(wt,a-1) 'NO PRELOAD FOR LEFT SIDE
            w4=wr
            op=1
            skiplspace(s,i)
            goto oploop
          end if
        end if
      end if
      '
      stdcompare:
      '==========
      '
      w2=cvta(typc,cpuw) 'fill temp bits / conversion
    end if 'CPU INTEGERS
    '
    'ALL TYPES
    '
    if isfpu(tp)=0 then
      w4=tmpvar()
      wt+=w2+operi(2,cpuw,w4)
    end if
    op=1
    goto oploop 'FOR RIGHT SIDE
  end if 'COMPARATORS
  '
  '
  '=======
  ncompar:
  '=======
  '
  '
  'IS END OF EXPRESSION?
  '
  if isendofexpress(s,i) then
    if cnd then
      if isfpu(typc) then
        if cp=0 then
          wt+="fldz"+cr+"fcomip st1"+cr+"fstp st0"+cr+_
          "mov "+qeax+cm+"0"+cr+"jz fwd _cnd"+cr+"dec "+qeax+cr
        end if
      end if
    end if
    goto xassigns
  end if
  '
  'CHECK FOR NEXT OPERATOR
  '
  b=i+1
  op=identop(s,i,b)
  if op then ctop+=1
  '
  'IF NO OPERATOR FOUND THEN ASSUME IT IS '+'
  '
  if op=0 then
    op=43
  else
    i=b
    nextinstruct(s,i) 'EXPLICIT OPERATOR IGNORES COMMENTS AND LINE ENDS
    if op=94 then
      wt+=cvtai(typc,&h68)
      typc=&h68 'A^B power of
    end if
  end if
  '
  goto oploop
  '
  '
  xassigns:
  '========
  '
  if noto then
    wt+=operi(11,typc,"")
    noto=0 'NOT
  end if
  '
  'NO FURTHER OPERATOR SO
  'ASSIGN TO LEFT OR MAKE COMPARISON
  '
  'STRING ACCUM: join strings
  '--------------------------
  '
  if jn then
    if funi then lcl=1 : lcls=1
    if typc<&h80 then
      wt+=numtostr(typa1,typc)
      typc=typa1
    end if
    '
    'CONCATENATE NOW (OTHERWISE CONCAT ON ASSIGN)
    '
    if iszstr(typa1)=0 then 'exclude zstring variable assigns
      if typa1 then typc=typa1
      if typc<&h80 then typc=1 'STRING TO VAL CONVERSION LATER
      typc=upgradelen(&hc1,typc)
      wt+=operi(96,typc,"") 'CONCATENATE
      if (parx>0)or(typa1<&h80) then wt+=logas() 'mark as temp for deletion
    end if
  end if
  '
  '
  'NON NESTED COMPARATORS
  '----------------------
  '
  if cp then
    '
    'STRING OPTIMIZATION
    a=isstr(typc)
    if a then
      if (op<2)and((typc and 31)=1)and((tp and 31)=1) then
        a=instrevn(-1,wt,"|op 2 ") 'FIND 'SAVE TO TEMP'
        b=instr(a+1,wt,"|cv ") 'TO EXCLUDE CONVERSIONS
        if b=0 then
          typ=typa
          a=instr(a+1,wt,cr)+1
          if usx then
            wt=left(wt,a)+wp
            if isdstr(usx) then wt+=logas()
          else
            nstod=1
            wt=left(wt,a)+makestrptrfun(wr) 'REMOVE CAT CODE FOR DIRECT COMPARE
            nstod=0
            if dts>0 then
              dts-=1 'NO TEMP STRING ON RIGHT SIDE
            end if
          end if
        end if
      end if
      usx=0
      a=1
    end if 'isstr
    '
    'DIRECT JUMP (OPTIMISATION)
    'but not for strings (due to garbage collection call)
    '
    if (a=0)and(ctal=1)and(nst=0)and(dts<=0) then
      if cnd=1 then cp xor=1 'OPPOSITE LOGIC
      cp+=&h70
      ctal=-16
    end if
    '
    wt+=cvtai(typc,tp)+operi(cp,tp,w4)
    typc=tp 'itr boolean?
    op=cp
    '
    if cnd=0 then typc=cpuw 'IIF EXPRESSION : A>B ? A : B
    '
  end if 'cp
  '
  '
  'PREPARE FOR ASSIGNMENT
  '----------------------
  '
  if (typa1)and(cnd=0) then
    if parx then typa=typc 'ENSURE ANY 'convert' STICKS
    wt+=cvtai(typc,typa1) : typc=typa1 'CONVERT TO ASSIGNMENT TYPE
  end if

  '
  nassignt: 'RECORD STATE AT END OF EXPRESSION
  '========
  '
  ascw=asc(wr) : wg=wr
  skiplspace(s,i)
  opg=op or uex : op=0
  'uex flag 'ALWAYS USE FULL EXPRESSION (not a variable)
  typ=typc
  '
  if opg<2 then
    typg=typa
  else
    typg=typc
  end if
  '
  if len(ppfx) then wt+=ppfx : ppfx=""
  '
  return wt
  '
  exitexpr:
  '========
  '
  end function 'expressions
  '
  '
  '---------------------------------------------------------------------------------
  function arrayres(byref s as string, byref i as sys, byref wr as string) as string
  '=================================================================================
  '
  dim as sys a,indi,opi,mpi,mci=mc,typv,ni,varfi,cndi
  dim as string wf,wri,sigi,sogi,oui
  '
  'SAVE STATE
  '
  opi=op
  mpi=mp
  varfi=varf
  cndi=cnd
  oui=ou
  sigi=sig
  sogi=sog
  '
  op=-1
  typv=typ
  tye=0
  varf=0
  cnd=0
  arf=opi 'FLAG ARRAY OPERATOR (assign=2 etc)
  parx+=1
  indi=ind
  '
  if indi then
    if cpoint then
      wri=wr : wr=pedi
      ni=isptr(ou,1)
    end if
  end if
  wu=wr
  wf=express(s,i,typv) 'MAY BE RECURSIVE
  if indi then
    if cpoint then
      wpfx=""
      indiri(wri,ni+1)
      wf=wpfx+wf
    end if
  end if
  if varf then
    if varf>10 then varf=10 'object offset resolved: this.obj[n].act
    varfi=varf 'pass back
  end if
  wr=wg
  '
  parx-=1
  '
  typ=typv 'CHANGE TYPE IF ELEMENT
  '
  'RESTORE STATE
  '
  ind=indi
  op=opi
  mp=mpi
  mc=mci
  varf=varfi
  cnd=cndi
  sig=sigi
  sog=sogi
  ou=oui
  arf=-1 'set array resolution flag
  return wf
  '
  end function
  '

'-------------------------------------------------------------------------------------------
function precalc(byref s as string, byref i as sys, ty as sys, byref w1 as string) as string
'===========================================================================================
  dim as sys a
  dim as string w2, w3
  w2=tmptypvar(typename(ty))
  a=me-1 : op=1
  w3=express(s,i,ty)
  w3=epfx+w3+operi(2,ty,w2)
  if dts>0 then
    w3+=rtl(deltmpa)
    dts=-1 'deleted temp strings
  end if
  skiplspace(s,i)
  op=0 : epfx=""
  w1+=w3
  return macso(a,0)
end function


'------------------------------------------------------------
function findas(byref s as string, byref wr as string) as sys
'============================================================
  dim as sys j
  j=instr(s,","+wr+"=")
  if j then function=j+len(wr)+2
end function


'----------------------------------------------------------------
sub replas(byref s as string, byref i as sys, byref wr as string)
'================================================================
  dim as sys j
  j=i
  capts(s,i)
  s=left(s,j-1)+wr+mid(s,i)
  i=j+len(wr)
end sub


'------------------------------------------------------------
function stripas(byref s as string, byref v as string) as sys
'============================================================
  ' (,a=3,b=4,) becomes (   3,  4 )
  dim as sys i=2,j,k,fd
  dim as string wr
  v=""
  do
    wr=tword(s,i)
    k=swd
    if lenw=0 then exit do
    if ascw=44 then
      if (ascn=rbr)or(ascn=125) then
        mid(s,2)=" " : mid(s,swd)=" " : exit do 'REMOVE LEFT AND RIGHT ,
      end if
      j=i
      wr=tword(s,i)
      if (ascn=44)or(ascn=61) then v+=wr+cm 'REBUILD PROTOTYPE
      if ascn=44 then
        if fd then mid(s,k)=space(i-k) 'BLANK OUT UNDEFINED TERM
      elseif ascn=61 then
        fd=1
        i+=1
        if mid(s,i,2)=".," then exit function 'ERROR
        mid(s,j)=space(i-j) 'BLANK OUT
        capts(s,i) 'STRIDE STATEMENT
      end if
    end if
  loop
  v=left(v,len(v)-1) 'remove final comma
  return 1
end function


'------------------------------------------------------------------------------------------------------------------
function subsas(byref s as string, byref i as sys, byref ur as string, byref v as string, byval igb as sys ) as sys
'==================================================================================================================
  dim as sys a,j,b=i,c,f
  dim as string wr,u=ur
  if (ascn<>rbr)and(ascn<>125)and(isxn) then
    goto nsubsloop   'NO PARAMS OFFERED
  end if
  do
    if igb then
      nextinstruct(s,i) 'LINE INSENSITIVE WITH BRACKETS
    else
      skiplspace(s,i)
      if iss(ascn) then exit do 'END OF STATEMENT EXIT
    end if
    '
    wr=tword(s,i)    'RBR, COMMA OR WORD
    '
    if (ascw=41)or(ascw=125) then
      exit do 'END BRACKET
    end if
    if ascn<>61 then
      i=swd : wr=captsx(s,i) 'CAPTURE WHOLE EXPRESSION
      f=instr(f+1,u,"=")
      if f then
        a=f+1
      else
        a=0
      end if
    else 'ascn=61
      i+=1 'SKIP '='
      a=findas(u,wr) 'LOCATE PARAM
      wr=captsx(s,i) 'CAPTURE EXPRESSION
    end if
    if a then
      replas(u,a,wr) 'REPLACE PARAM WITH EXPRESSION
    else
      i=b : exit function 'FAIL
    end if
    skiplspace(s,i)
    if ascn=44 then
      i+=1 : continue do 'NEXT PARAM
    end if
    if igb then
      nextinstruct(s,i)
      i+=1 : skiplspace(s,i) 'SKIP RIGHT BRACKET
    end if
    exit do
  loop
  '
  nsubsloop:
  '
  if stripas(u,v) then  'STRIP B=, C=  LEAVING PARAM EXPRESSION ONLY
    inserts(s,u,i)  'INSERT RESULTING PARAM LIST
    skipspace(s,i) 'SKIP TO OPENING BRACKET
 return 1 'FLAG SUCCESS
  else
    i=b  'PARAM ERROR
  end if
  end function


  '-------------------------------------------------------------------------------------------------------------
  function namedparams(wr as string,byref s as string, byref i as sys, byval igb as sys, byref ct as sys) as sys
  '=============================================================================================================
  dim as sys a,b,k,kk,kr,m,oo,sb,vf
  dim as string wd
  '
  vf=varf
  if vf=8 then
    m=mp : oo=1
  else 'vf>8
   m=maco(mp,0)-htyp : oo=-1
  end if
  '
  dvl=macso(m,1)
  do
    dvm=""
    '
    kk=ascn
    if vf=8 then
      nextproc(dvl,oo,wd,0)
      ascn=kk
    else 'vf<>8 METHODS
      findmemb(wr,wd,oo,a) 'locate prior matching name (reverse order)
    end if
    ascn=kk
    '
    if oo=0 then
      exit do 'NO FURTHER FINDS
    end if
    ct+=1
    if len(dvm) then
      k=1
      sb=subsas(s,i,dvm,"",igb)
      if sb then exit do   'SUCCESFUL SUBSTUTION
    end if
  loop
  '
  if k then
    if sb=0 then
      ers="unable to match param names" : ert=106
      k=0
    end if
  end if
  '
  return k
  '
  end function
  '
  '
  '
  '====================================================================================
  '
  '
  '   ########    ########     #######     #######
  '   # PROCS #   #       #   # RECUR #   #       #
  '   #       #   #       #   #       #   #                   #
  '   #       #   #       #   #       #   #           ###########  CALL + EXPRESSIONS
  '   ########    ########    #       #   #                   #
  '   #           #   ##      #       #   #
  '   #           #     ##    #       #   #       #    
  '   #           #       ##   #######     #######
  '
  '
  '-----------------------------------------------------------------------------------
  function procedures(byref s as string, byref i as sys, byval wr as string) as string
  '===================================================================================
  '
  ' predefine sig
  dim as sys mqp,typp,a,b,c,d,k,m,ct,pb,pn,po,cc,qf,ofpu,igb,eqf,cbj
  dim as sys wff,tff,lid,vp,lvaf,stk,sti,px,cts,lv,lb
  dim as string w1,w2,w3,w4,w5,w6,paramcode,wd,we,wp,wo,ws,wf
  dim as string sigs,sigd,rgst
  '
  'FUNCTION CALL
  '-------------
  '
  '
  lcl=1
  parx+=1
  w4=wr : if w4="fwd" then  w4+=" "+mword(s,i)
  '
  '
  'RECURSION SUPPORT
  '-----------------
  '
  'procedures with parameters containing procedures
  '
  mqp=mp
  typp=typ
  sigs=""
  vp=varf
  tff=toff
  stk=stkb
  wp=ow
  if asc(ow)=lbr then
    wp=macso(mp,0)
  end if
  w5=wpfx
  stkb=0
  rgst=regst
  '
  ct=maco(mp,0)
  if ct>htyp then
    if varf=8 then ct=-5 'FUNCTION TABLES
  end if
  lvaf=vaf : vaf=vp      'methods with parameters containing methods
  pb=pc                  'param stack index
  '
  '
  'itr linux calling conventions
  '
  'PROVISIONAL BEFORE SIGNATURE MATCHING
  cc=ccx
  '
  if ct=-4 then
    'UNPROTOTYPED CALLS
    nextproc(macso(mp,1),1,w4,lb)
    cc=cco
    if lb>0 then
      w4=addlproc(lb,w4) 'GET VECTOR (OR CREATE IT)
    end if
  elseif ct=-17 then
    cc=17 'FPU CALL
  end if
  '

  if cc=0 then
    if cpuw=8 then cc=2 'MS64
  end if
  '
  '
  'RESOLVE ELEMENT NAME
  '--------------------
  '
  'IS CLIPPING FIRST PART OF NAME REQUIRED?
  '
  c=instr(wp,".")
  if c then we=mid(wp,c+1) else we=wp
  '
  '
  '
  'LOOK AHEAD FOR LEFT BRACKET
  '---------------------------
  '
  a=i : nextinstruct(s,i)
  '
  if ascn=lbr then
    igb=1 : i+=1    'IGNORE ( .. )
    nextinstruct(s,i)
  else
    i=a : skiplspace(s,i) 'RESTORE PRIOR POSITION
  end if
  '
  a=4
  select case ascn
  case 41 : a=1 '()
  case 61 : eqf=1 : i+=1 : skiplspace(s,i) 'MARK ONE-PRAM PSEUDO-ASSIGN f=...
  case 91 : '[ drop thru
  case 44 : goto xparams ',
  case 43 : goto xparams '+
  case 47 : goto xparams '/
  case 92 : goto xparams '\
  case else
    if isendofexpress(s,i) then
      a=1 'no params offered, possibly optional or default params
    else
      w1=wordahead(s,i) 'could be named param
      'SELECTED PARAM MODE? eg (b=4,c=5)
      if asc(s,nwd)=61 then
        a=2
      end if
    end if
  end select
  '
  'MACRO EXPANSION OF PARAM SETS
  '-----------------------------
  w1=wordahead(s,i)
  if isa(asc(w1)) then
    m=lookupm(w1)
    if mp then
      if maco(m,0)=-18 then
        i=nwd
        wr=macres(m,s,i) 'LOW LEVEL MACRO ONLY
        inserts(s,wr,i) : skiplspace(s,i)
      end if
    end if    
  end if
  '
  '
  if a then
    '
    b=namedparams(we,s,i,igb,cts)
    '
    if a=2 then
      if b=0 then
        ers="Default Params not available" : ert=110
      end if
    end if
    '
    if ert then exit function
    '
    if b then i+=1 : igb=1 'skip left bracket & will ignore right bracket

    if isxn then
      if eqf=0 then goto xparams 'NO PARAMS PROVIDED
    end if
    '
  end if
  '
  '=========================
  'PROCEDURE CALL PRODUCTION
  '=========================
  '
  'RECURSIVE:  PROC ----> EXPRESSIONS CONTAINING PROCS
  '
  '------------------------------------------------------------------
  '
  ' CALLING-CONVENTION -> PARAMS-REGS/STACK -> 
  '
  ' PARAMS -> EXPR + TYPE -> BUILD-SIG -> MATCH-SIG -> CONVERSIONS ->
  '
  ' BYVAL/BYREF -> TEMP-STORAGE ->
  '
  '
  ' CALL-DIRECT/INDIRECT/METHOD -> CLEANUPS -> COMPOSE
  '
  '
  pdr+=1 'PROCEDURE NESTING DEPTH COUNTER
  do ' each param
    '
    if (ascn=123)or(ascn=125) then
      exit do
    elseif (ascn=&h65)or(ascn=&h74) then
      if instrword(" then else elseif endif end to ",wordahead(s,i) ) then exit do
    end if
    '
    'LOOSE TYPE IDENTITY
    '
    lid=0
    if (ascn=38)or(ascn=42)or(ascn=63) then
      lid=1
      if ascn=38 then a=ascl(s,i+1) : if (a=&h68)or(a=&h6f) then lid=0 'avoid &h &o
    end if
    '
    qf=0 : sog="a" : w1=""
    pc+=1    'PARAM COUNTER
    pn+=1    'PARAMETER NUMBER COUNTER
    po=pc    'RETAIN COUNTER DURING RECURSION
    ofpu=fpu 'RETAIN FPU FLAG
    sti=0    'param stack allocation increment
    '
    'CHECK FOR LOWER PROCEDURES
    '
    a=1
    if (ct=0)or(ct=-4)or(ct=-18)or(ct=-19)or(ct=-20) then a=0
    '
    '
    '==========
    'PROCEDURES
    '==========
    '
    b=0 : c=48 : sog="" : op=0 : typg=0
    '
    if cc=17 then b=&h68 'FPU INTRINSICS
    '
    wd=express(s,i,b) : if ert then goto xprocs
    '
    k=asc(wg)
    '
    if bvg then c=95 '_' BYVAL: TURN OFF TYPE MATCHING
    '
    'FPU CALLING CONVENTION OR OTHERWISE
    if cc=17 then 'FPU
      '
      w1=""
      '
    else 'cc<>17 (not fpu)
      '
      if typg=0 then typg=cpuw 'default type
      '
      'PRECALC PARAMS CONTAINING CALLS (RECURSIVE)
      if opg>=1024 then
        b=typg
        d=ascn
        if b>=&h80 then b=cpuw 'STRINGS AND HIGHER TYPES
        w2=newtmpvar(typename(b))
        wg=macso(me-1,1)
        epfx+=wd+operi(2,b,wg)
        wd=operi(1,b,wg)
        opg=1024
        ascn=d
      end if 
      '
      if (a=0)and(opg<=1) then 'UNPROTOTYPED
        if isstr(typg) then
          dts-=1
          typ=typg
          makestrptr(wg)
        end if
        '
        if cpuw=4 then
          noprototype(wd,w1)
          w1=operi(4,typg,w1)
          sti=cpuw
          stkb+=sti
          goto dparams
        end if
      end if
      '
      '
      if cpuw=8 then
        '
        if (opg<=1)and(a=0) then
          noprototype(wd,w2)
        else
          w2=cpua
        end if
        '
        b=cco : cco=cc
        w1=callcnvi(pn,w2,0)
        cco=b
        '
        if (cc=2)or(cc=3) then
          if vaf>8 then b=1 else b=0
          if pn+b>4 then sti=cpuw 'itr simd registers
        else
          sti=cpuw
        end if
      else 'cpuw=4
        b=typg : if b>=htyp then b=cpuw
        w1=operi(4,b,"") 'DEFAULT
        sti=cpuw
      end if
      '
      stkb+=sti
    end if 'fpu / not fpu
    '
    if a=0 then
      goto dparams 'NO SIGNATURE
    end if
    '
    '
    '---------------
    'BUILD SIGNATURE
    '===============
    '
    'to match with overloadable procs
    '
    'GENERAL TYPES
    '
    if (lid>0)and(opg<2) then
      sog="sys"
    elseif typg<htyp then
      a=typg and &h7fffffe0
      if a=&hc0 then
        a=typg+32
      else
        a=typg 'bstring gets labelled as string
      end if
      sog=typename(a)
      if sog="" then sog="any"
    end if
    '
    a=opg and &h3ff
    if a<2 then
      if (typg>=htyp)or(len(wpfx)) then
        if c<>95 then
          if isq(asc(wg)) then
            'excluding o2 literal strings
          else
            c=49 'default byref
            if ind then c=48+ind
            if asc(wpfx)=46 then
              'strptr etc
              if instr(wpfx,"._direct_")=1 then c=48
            end if
          end if
        end if
      end if
    end if
    '
    sigs+="#"+sog
    sigd+=chr(c)
    '
    '
    '
    dparams: 'bypass signature building for low level calls
    '======================================================
    '
    '
    if ert>0 then goto xparams
    '
    '----------------------------------------
    ' CAPTURE EXPRESSION TYPE CONVERSION CODE
    ' REFERENCING / DEREFERENCING CODE
    ' TEMP STORAGE
    '========================================
    '
    pc=po : fpu=ofpu ' RESTORES AFTER RECURSION
    '
    por(pc)=ow   'LAST WORD
    paw(pc)=wg   'LAST OPERAND
    pas(pc)=wd   'LAST EXPRESSION
    pat(pc)=typg 'LAST TYPE RETURNED
    pao(pc)=opg  'LAST OPERATOR
    pav(pc)=w1   'DEFAULT COMPATIBILITY CODE (usually push eax)
    pax(pc)=wpfx 'INDIRECT
    pst(pc)=sti  'STACK INCREMENT
    '
    '============================
    nparams: 'CHECK END OF PARAMS
    '============================
    '
    '
    if iss(ascn) then
      '
      'RIGHT BRACKET CHECK AHEAD
      '
      a=i : b=ascn : nextinstruct(s,i)
      if ascn<>rbr then i=a : ascn=b : exit do
    end if
    '
    '
    if ascn=rbr then
      if (cnd=0)and(nst<2) then
        a=i+1
        if wordahead(s,a)="=" then
          i=nwd
          igb=0   'itr err trap missing left bracket?
          continue do 'COMMAND FUNCTIONS
        end if
      end if
      exit do
    end if
    '
    if ascn=44 then i+=1 : nextinstruct(s,i)
  '---------------
  loop 'NEXT PARAM
  '---------------
  '
  pdr-=1
  '
  '=======
  xparams:
  '=======
  '
  '
  pls="0"
  '
  if igb then
    if ascn=rbr then
      i+=1
    else
      ers="Missing right bracket" : ert=124 : exit function
    end if
  end if
  '
  pas(pc+1)="" 'CLEAR AFTER-CALL CODE
  skiplspace(s,i)
  '
  '
  if tranpass=1 then
    pc=pb
    goto xprocs 'NO PARAM MATCHING OR CALL ENCODING
  end if
  '
  'SIGNATURE MATCHING (typ is also identified)
  '-------------------------------------------
  '
  uk=1     'REQUIRE EXACT PARAM MATCHING
  typ=typp 'DEFAULT TYPE
  cco=cc   'PRESET CALLING CONVENTION
  mtyp=0   'CLEAR METATYPE
  '
  if (vp>8)or(ct=-5)or(ct=-16) then
    '
    'whole signature matching
    '
    if len(sigs) then
      sigs+="@"+sigd ' 1/0 byref/byval
    else
      sigs="#@"
    end if
    '
    if vp=8 then
      if instr(wp,".")=0 then 
        ws=macso(mqp,1) : uk or= 8 'REQUIRE PARAM MATCH FOR FUNCTIONS
      end if
    end if
    '
    '
    'MATCH FOR OVERLOADED PROCEDURES
    '-------------------------------
    '
    'FOR FUNCTIONS/SUBS/OPERATIONS (nextproc) AND METHODS (findmemb)
    '
    if cts<=1 then
      uk or=6 'ALLOW ANY CONVERSION. NO OVERLOADING AVAILABLE
    end if
    mp=mqp
    '
    rmatchproc:
    '==========
    '
    w2=""
    m=0
    '
    a=uk and 8
    if a=0 then
      k=-1
    else
      k=1
    end if
    '
    do
      if a then 'MATCH FUNCTIONS
        nextproc(ws,k,we,lb)
        cc=cco
      else 'MATCH METHODS
        findmemb(we,wd,k,m)
        if k then 
          if (varf=5)or(varf=6) then
            k=0 'group header located
          else
            cc=cco 'calling convention
          end if
        end if
      end if
      '
      '
      if k=0 then
        exit do 'fail
      elseif sig="" then
        exit do 'unprototyped
      end if
      '
      stkb=0 'FOR COMPATSIG CDECL
      '
      if compatsig(sigs,sig,pb) then
        if ert then goto xprocs
        exit do 'success
      else
        '
        'BUILD OVERLOADED FUNCTIONS LIST
        '
        if (uk and 4)=4 then
          if sog="bstr" then sog="string"
          if len(sog)=1 then sog=""
          if len(sog) then sog=" returns "+sog
          w3=splitsi(sig,w6) 'remove indirection codes
          replace(w3,"#",",")
          w2+=wp+"("+mid(w3,2)+")"+sog+cr
        end if
      end if
    loop
    '
    '
    if k=0 then
      if (uk and 2)= 0 then
        uk or=2 : goto rmatchproc 'TRY AGAIN ALLOWING LIMITED TYPE CONVERSIONS THIS TIME
      elseif (uk and 4)=0 then
        uk or=4 : goto rmatchproc 'TRY AGAIN ALLOWING NUMBER<->STRING CONVERSIONS
      end if
    end if
    '
    uk=0     'must be set to 0 when done
    wff=woff 'OFFSET
    '
    '
    '-------------------
    'MATCH UNSUCCESSFUL?
    '===================
    '
    if k=0 then
      ers="parameters mismatch for procedure "+wp+cr+_
      "params given : "+sigs+cr+cr+"OPTIONS:"+cr+w2+cr
      ert=13
    end if
    '
    matchok:
    '========
    '
    if ert then goto xprocs
    '
    '
    cc=cco   '
    ct=-mtyp '0 IF A METHOD
    '
    if ct=-5 then
      if (lb>0) then  'IMPORTED FUNCTIONS
        we=addlproc(lb,we) 'GET VECTOR (OR CREATE IT)
      end if
    end if
    if (ct=-5)or(ct=-16) then
      '
      'FORMULATE CALL NAME
      '
      a=asc(we)
      if isn(a) then
        w4="["+qebx+"+"+we+"]" 'GLOBAL VECTORED CALL
      elseif a=91 then
        w4=we
      else
        w4=we 'NAME WITH NAMESPACE
      end if
      '
      'IS CHAR WIDTH INFO REQUIRED? (built-in string functions only)
      '=============================================================
      '
      if ct=-16 then
        if instrword(" string ",wp) then
          typg=pat(pb+2) 'check type of second param
        elseif instrword(" space nuls stringbytes ",wp) then
          if isstr(typp) then
            typg=&hc0 or (typp and 31) 'the char width expected by the assignee
          else
            typg=&hc1 'ASSUME BYTE BSTRING
          end if
        elseif instrword(" left mid ",wp) then
          typg=pat(pb+1) 'check type of first param
        end if
        '
        if isstr(typg) then
          a=typg and 31
          w5+=enc("ch "+chr(48+a)) 'charwidth(a) 'cast string param
        else
          a=0
        end if
        '
        if isstr(typ) then
          typ=upgradelen(typ,a) 'cast string width according to a string param
        end if
      end if
    end if
    '
    skiplspace(s,i)
    '
  end if ' END OF SIG MATCHING
  '
  if ert then goto xprocs
  '
  '
  '
  '
  ' #######
  ' # CALL # 
  ' #      #
  ' ####### 
  ' # METH #
  ' #      #
  ' #######
  '
  '
  'RESTORE STATE VARIABLES
  '
  varf=vp
  toff=tff
  woff=wff
  mp=mqp
  regst=rgst
  '
  'BUILD PARAMETER BLOCK
  '
  paramcode=buildparamblock(pb,cc)
  w1="" 'space allocate
  w2="" 'space disallocate
  a=instr(wp,".")+1
  w3=w5+preparecall(wp,w4,mid(wp,a)+splitsi(sig,w6),cc)
  a=0 'temp storage value
  b=0
  '
  '
  'ALLOCATE SPACE FOR LOCAL TEMP STORAGE
  '
  if cpuw=8 then a-=tmpstk
  '
  if a<0 then
    w1=enc("sp "+str(a))
  end if 
  '
  'SPACE DISALLOCATION
  '
  if cc=1 then
    b=stkb  'CDECL STACK CLEANUP N BYTES
  else
    b=0
  end if
  '
  'ALSO DISCARD TEMP STORAGE
  '
  if cpuw=8 then
    b+=tmpstk 'for reg spill zone ms64 calling convention
  end if
  '
  '
  if b then
    w2=enc("sp "+str(b))
  end if
  '
  'RELEASE TEMP STORAGE OFFSET (but not for statics)
  '
  '
  '======
  xprocs:
  '======
  '
  'FREE PARAM STACK
  '
  pc=pb : vaf=lvaf 'VARF USED BY CALLCNV() TO OFFSET OOP PARAMS
  stkb=stk 'PRIOR BYTES ON STACK
  '
  '
  parx -=1
  return w1+paramcode+w3+w2
  '
  end function ' procedures
