
  '==========
  'TRANSLATOR
  '==========

  declare function PrepExec() as string


  'RESOLVE HIGH LEVEL EXPRESSION, MACROS ETC INTO ASSEMBLER


  '--------------
  sub translate()
  '==============

  '===========================
  'LOCAL VARIABLES DESCRIPTION
  '===========================

  ' s     source string
  ' fp    include string index
  ' qf    inline quote flag
  ' i     source index
  ' sst() source string buffers for include
  ' a     general ascii value
  ' k     general purpose
  ' m     general purpose
  ' n     general purpose
  ' v     general purpose
  ' w     general purpose
  ' w1.w9 param
  ' wc    case expression
  ' wd    word string
  ' wr    word string
  ' wm    word string
  ' wn    word string
  ' ws    word string
  ' wt    word string
  ' wv    last variable name dim
  ' typo  type definition flag
  ' aoff  offset value for local vars etc
  ' poff  previous offset
  ' sregs nesting for indexers
  ' asce  ascending/descending flag
  ' regs  macro used to specify index regs for variables
  ' adr   address indirection flag for proc params
  ' mq1   hold index mq
  ' mqp   proc mq
  ' op1   hold op
  ' opp   proc op
  ' sih   single inheritance
  '-------------------------
  ' typa  type of variable
  ' typm  type of first variable
  ' typc  type of accumulator in use
  ' typp  return type of procedure
  ' ccp   call convention type of provedure
  ' typl  left hand (assigment type in use
  ' bs    bracketed expression present and skipped
  ' va    hold varf
  ' bv    byval flag
  ' tpt   indirection counter
  ' ali   alias   for imported or expoted functions
  ' lby   library for imported functions
  ' it    identified type
  ' atf   flag indicating exported function
  ' lcl   flag stack params or locals
  ' lcls  flag local/param strings used
  ' blcl   block local ebp code (positions)
  ' tm    t marker for splitting t
  ' fdd   def flag
  ' fro   for flag
  ' prf   private flag for inherited elements
  ' noin  noinit flag prevents local vars being set to 0
  ' ctbl  class table flag
  ' eord  export ordinal counter
  ' mage  binary image (for pe formatting)
  ' clsi  class record index
  ' reto  tally offset for ret n instruction
  ' retb  tally base offset for ret n instruction
  ' ml    mp lower local boundary holder
  ' tdst  typedef struc flag
  ' un    outer union flag
  ' dcp   declared C prototype
  ' deco  C style typdef function function flag
  ' pn    parameter counter for function prototypes
  ' ccx   calling convention extern block default
  ' atx   external flag block default for proc internals
  ' dtx   temp state of etx
  ' etx   export flag block default for proc internals
  ' opa   flag for optional params
  ' typd  inferred type in dim/declare statements
  ' cnsl  console mode flag for PE file SubSytem 3 (normally 2)
  ' bpb   Block param bracket flag
  ' epi   Epilog flag
  ' typf  default type (c style prototype)
  ' df    indirection count (c style prototype)
  ' dg    default type (prototype default type establish flag)
  ' fc    byval/byref spec
  ' bj    mark start of output code block (#show)
  ' pf    pointer function flag
  ' cbj   cbuf position
  ' sw    first word in statement
  ' pch   generic zstring/char pointer
  ' sln   single line conditional
  ' ttc   class table entries tally
  ' tuc   class tabel inherited entries
  ' wfn   function / sub / method
  ' opss  operator string
  ' shf   #show filename
  ' shs   #show source line
  ' dfv   default value flag for prototypes

  '===============
  'LOCAL VARIABLES
  '===============


  dim as sys a,b,c,d,e,f,g,i,k,m,n,p,q,u,v,w,qf,typo,poff,pk,adr,mq1
  dim as sys bs,va,bv,tpt,it,tm,fdd
  dim as sys op1,typa,typc,lent1,mqp
  dim as sys opp,fro,ctbl,clsi,tdst,un,dcp,deco
  dim as sys pn,atx,dtx,etx,opa,typd
  dim as sys bpb,epi,typf,df,dfv,dg,fc,bj,pf,cbj,funbr,sln,ttc,tuc

  dim as sys relaxed=0
  dim as long ptr pm

  dim as string w1,w2,w3,w4,w5,w6,w7,w8,w9,wd,wm,wn,wr,ws,wt,wv,s
  dim as string ali,lby,prf,mage,wc,sw,wfn,opss,shf,shs
  dim as zstring ptr pch

  
  '==============
  'INITIALISATION
  '==============
  '
  '
  start_prep:
  '
  s=gsrc+cr 'gsrc global source
  t=space(len(s)*2+1000)
  '
  i=1 : j=1 : cbi=1
  '
  mex=len(s)*10+100000
  if mex<2e6 then mex=2e6

  GlobalClear()
  regnames() 'DEFAULT TO 32 BIT REGISTERS


  'skiplspace(s,i) : wr=wordahead(s,i)

  'if (dep)and(me>0) then
  if dep then
    goto mainstart 'BYPASS FOR RUN-TIME COMPILING
  end if
  '
  depsp=0
  '
  'STATICS OFFSET
  '--------------
  '
  'The run-time function table is combined with static variable table 
  '
  aoff=&h1000 'ALLOWING FOR RTL TABLE
  aoffs=aoff

  InitDefTables()

  ixb=1 'DEFAULT INDEX BASE


  '===============
  'LOAD INTRINSICS
  '===============

  restore kernel_funs : Intrinsics()
  restore x86_registers : Intrinsics()
  '
  'LIST OF REFERENCED DECLARATIONS (FROM PASS 1)
  '
  'if (tranpass>1)and(dlistend>1) then
  '  b=1
  '  c=0
  '  while b<dlistend
  '    wr=tword(declist,b)
  '    maco(me,0)=-101
  '    macsi(wr,me,0)
  '    addm() : addme()
  '    if ert then goto exitap
  '    c+=1
  '  wend
  '  c=0
  'end if
  '
  'if preproc=0 then lineprep(s) 'processes raw declarations
  '
  'FIRST WORD COMMANDS
  '
  'to come before declarations
  '
  '
  w1=wordahead(s,i)
  if w1="#view" then vew=2 : i=nwd
  if w1="#prep" then vew=3 : i=nwd
  '
  '
  '####################
  '####################
  '
  ' #######    ######                  #
  '  ##    #  #      #                 ##
  '  ##    #  #      #  ###################
  '  ##    #  #      #  ### MAIN ############
  '  ##    #  #      #  ###################
  '  ##    #  #      #                 ##
  ' #######    ######                  #
  '
  '####################
  '####################
  '
  mainstart:
  '=========
  '
  regs=regss 'STATIC REGISTER QEBX
  mest=me    'LOCAL DEFINITIONS FENCE
  mesb=me    'CORE DEFINITIONS FENCE
  '
  '
  '========================
  mainloop: 'main line loop
  '========================
  '
  skiplspace(s,i)
  '
  newline:
  '
  nl=1
  typm=0
  op=2
  '
  if sln then
    if ise(ascn) then
      'CLOSE 'IF' SINGLE LINER
      md=17
      goto endcons
    end if
  end if
  '
  '
  '======================
  do 'main statement loop
  '======================
  '
  '
  if ert then goto exitap
  sig=""
  '
  op=0
  wr=pword(s,i)
  '
  if nl=1 then sw=ow
  '
  '
  select case mc
  '
  case 0
  '
  ' --- === comment line
  '
  if (ascn=43)or(ascn=45)or(ascn=61)or(ascn=46) then
    if ascw=asc(s,swd+1) then
      if ascw=asc(s,swd+2) then
        endline(s,i) : continue do '--- === comment line ... ellipsis
      end if
    end if
    '
    '++ -- PRE
    '
    if (ascw=43)or(ascw=45) then

      inserts(s,wr,i)
      goto generalexp
    end if
  end if
  '
  if isc(ascw) then 'COMMENTS
    a=ascn
    b=asc(s,i+1)
    endline(s,i)
    if a=33 then
      appendt(mid(s,swd,i-swd+2)) 'CAPTURE METACOMMENTS '!...
      goto mainloop
    elseif (a=95)and(b=34) then
      wr=mid(s,swd,i-swd)
      cfile=mid(wr,4)
      appendt(wr+cr) 'CAPTURE METACOMMENTS '_"...
      goto mainloop
    elseif a=lnm then
      wr="'_"+mid(s,swd+2,i-swd-2) : lnmks=mid(wr,3)
    elseif nl=1 then
      continue do 'omit
    end if
    goto addsrc
  end if
  '
  select case ascw
  '
  '
  case 58 'COLON : 
  '
  appendt(": ") :  goto mainloop 'COLONS AS STATEMENT SEPARATORS OR ASM PREFIXES
  '
  '
  case sr2 'POSSIBLE SEMICOLON AS SEPARATOR; 
  '
  appendt(cr) : ascn=13 : goto newline 'loop back
  '
  '
  case 35 'HASH #
  '
  b=asc(wr,2)
  if (b=35) then
    if asc(s,swd+2)=35 then
      '
      'VIEW MARKERS ###
      '
      if vwb=0 then vwb=1 : w1="#view" else vwe=1 : w1="#endv"
      appendt(w1+cr) : goto mainloop
    end if
    '##var runtime binding
    inserts (s,"proc [ebx+40] "+chr(34)+mid(wr,3)+chr(34)+cr,i)
    continue do
  end if
  if mp=0 then
    ers="Unidentified " : ert=20 : goto exitap
  end if
  '
  '
  case 123 'BRACE START BLOCK {
  '
  i=swd : cbrencah(s,i,0)
  if ert then goto exitap
  appendt(sp)
  goto mainloop
  '
  case hasa 'MID-LEVEL CODING MARKER 124 '!'
    endline(s,i)
    appendt(mid(s,swd,i+2-swd))
    goto mainloop
  '
  case 125 'BRACE END BLOCK }
  '
  if cbri>0 then
    cbri-=1
    a=cbrk(cbri)
    select case a
    case 0 :   appendt(ep) : goto mainloop
    case 1 :
      b=i
      nextinstruct(s,i)      
      w1=tword(s,i)
      if w1="else"   then md=15 : goto endcons 'ELSE
      if w1="elseif" then md=16 : goto endcons 'ELSEIF
      i=b  : md=17 : goto endcons  'END IF
    case 2 : md=18 : goto endcons  'END DO
    case 3 : md=19 : goto endcons  'END WHILE
    case 4 : md=34 : goto endcons  'NEXT
    case 5 : md=20 : goto endcons  'END SELECT
    case 1001 to 1100 : md=a-1000
    case 1101 to 1200 : n=a-1100 : goto endpro
    end select 'block type a
    goto endings
  end if
  '
  case 101 'e
  '
  if ow="end" then
    if isxn then
      if funi then
        w1="jmp fwd _end_proc"
      else
        w1="jmp fwd _end_"
      end if
      appendt(w1+cr)
      goto mainloop
    end if
    wr=tword(s,i)
    n=0 : md=0
    a=lookupm(wr)
    if a then
      if maco(a,0)=-14 then
        md=maco(a,5)
      elseif wr="namespace" then
        endline(s,i) : SetNamespace(s,i)
        goto mainloop
      end if
    end if
    goto endings
  end if
  '
  case 248 : '#SHOW END MARKER
    w2=shs+cr+">>>>"+cr+mid(t,bj,j-bj)+">>>>"+cr+itran(mid(t,bj,j-bj))+cr
    shs=""
    if len(shf) then
      open shf for output as 3 : print #3,w2 : close(3)
      shf=""
    else
      qq w2,1
    end if
    goto mainloop
  case 252 : appendt(enc("mk 1")) : goto mainloop
  case 253 : appendt(enc("mk 0")) : goto mainloop
  '
  end select 'ascw
  '
  '
  'mc selection continued ...
  '
  case -10 : if nl then typm=typ                'REGISTERS 
  case -13 : goto maino2                        'O2 KEYWORDS
  case -14 : nl=0 : goto maino2h                'O2H KEYWORDS
  case -19 : appendt(wr) : goto mainloop        'TERMINATION MACROS
  case -21 : appendt(macso(mp,1)) : continue do 'CODE MACRO
  case -32 : appendt(stodata(wr)) : continue do 'STRING LITERAL
  '
  end select 'mc
  '
  md=0
  '
  '++ -- POST
  '
  if typ then
    if ascn=asc(s,i+1) then
      a=0
      if ascn=43 then
        a=12
      elseif ascn=45 then
        a=13
      end if
      if a then
        w1=wpfx+operi(a,typ,wr) 'itr i++=
        i+=2
        goto cleardown
      end if
    end if
  end if
  '
  '
  'CHECK FIRST WORD IN STATEMENT
  '=============================
  '
  if nl then
    '   
    '
    select case ascw
    '
    case 36 to 37 '$ %  EQUATES
    '
    EncodeEquate(s,i)
    if ert then goto exitap
    goto mainloop
    '
    '
    case 48 to 57 'NUMBER LABELS
    '
    if ascn=58 then if i=swd+lenw then i+=1
    appendt("._"+wr+cr)
    continue do
    '
    case 91 'SQ BRACKET [
    '
    'if (varf=0)and(isxn)and(typ>0) then
    '  ert=100 : ers="Syntax:"+wr : goto exitap
    'end if
    '
    case 44 ' COMMA
    '
    ert=100 : ers="stray comma:" : goto exitap
    '
    '
    'BRACKETS FOR SCOPING
    '
    case 40 ' (
    '
    nest() : if ert then goto exitap
    appendt(sp)
    goto mainloop
    ' 
    '
    case 41 ' )
    '
    unnest : if ert then goto exitap
    appendt(ep)
    goto mainloop
    '
    case 61
    '
    op=1
    asxp=1
    w1=express(s,i,typm)
    asxp=0
    goto cleardown '=x left in accum
    '
    end select
    '
    '
    'LABELS
    '
    if ascw=46 then
      lbw=mid(wr,2)
      macoin(me) : macsi(lbw,me,0) : maco(me,0)=-30 : addm() : addme
      appendt(ow+cr)
      if ascn=58 then i+=1
      goto mainloop
    end if
    '
    if ascn=58 then '
      a=checkforlabels(s,i)
      if a then
        lbw=wr
        macoin(me) : macsi(lbw,me,0) : maco(me,0)=-30 : addm() : addme
        appendt("."+ow+cr) : goto mainloop
      end if
    end if
    '
    a=0
    '
    if mp then
      if ascw=91 then
        a=1
      elseif (mc>=0)and(typ>0) then
        a=1
      end if 
      if a then
        if varf=0 then if typ=0 then typ=cpuw
        typm=typ : mq1=mp
      end if
    else 'mp==0
      if ascw=91 then
        typ=cpuw : typm=typ
      end if
    end if
    '
    'TYPES 
    '=====
    '
  'INSTANTIATIONS (C STYLE DIM)
  '============================
  a=0
  select case mc
  '
  case -16 : if wr="string" then a=-1     'STRING PRIMITIVE
  case -33 : a=1                          'ENUMERATION
  case -3  : a=1                          'UDT/CLASS OBJECT
  case -15 :                              '
    if isn(ascn) then                     '
      if wr="int" then
        nl=0 : goto addsrc 'ASM INTERRUPT
      end if
    end if                                '
    a=-1                                  'C PRIMITIVE
    if wr="sys" then lent=cpuw : typ=cpuw 'SYSTEM INTEGER/POINTER TYPE
  case -8  :                              'TYPEDEF REFERENCE
    b=maco(mp,4)                          'locate func attributes  '
    if b=-5 then                          'PROCEDURE-ADDRESS TYPE
      wr="sys"
      inserts(s,wr+" ",i)
      goto mainloop
    end if
    m=b-htyp                              '
    a=1 'C style UDT variable 'VAR
  '
  end select
  '
  'CHECK FOR C STYLE DECLARATIONS
  '
  if a then
    '
    a=captpreproto(s,i,wr,w7)
    '
    'IS A VARIABLE (INCL ENUMERATION)
    '
    if (a=0)or(a=123) then
      if ascn=44 then i+=1 : nextinstruct(s,i) 'LINE FOLLOW-ON
      inserts(s,wr+" ",i)
      pf=0 : n=4 : goto directdim 'ALL NON-PROCEDURES
    end if
    '
    'OTHERWISE  A PROCEDURE
    '
    '
    fundec: ' ENTRY POINT FOR EG: TYPEDEF INT ( *FUNC) (LONG* pv,...);
    '======
    '
    'FUNCTION OR SUB
    '
    if wr="void" then
      w2="" 'NOTE THAT VOID* IS A FUNCTION
    else
      w2=wr
    end if
    '
    'if a=123 then 'int f {...}
    '  w3=w7
    '  if len(w2) then w3+=" as "+w2
    '  goto nproto
    'end if
    '
    w1=""
    if a=1 then                  'IS PROCEDURE POINTER
      pf=1                       'SET FUNCTION POINTER FLAG
      i+=1                       'SKIP LEFT BRACKET
      while ascn<>rbr
        wr=uword(s,i)            'DUMPS ANY MACRO OR '*'
        if ascw=lbr then
          i=swd : capture(s,m,i,0) 'SKIP INNER BRACKET CONTENT
        end if
      wend
      i+=1                       'SKIP RIGHT BRACKET
    else 'OTHERWISE DIRECT
      w1=""
      wr=uword(s,i)
    end if
    '
    nextinstruct(s,i)
    '
    w3=w1+wr+w7+translateproto(s,i,w2) 'function*abc() as x
    assieq(s,i)
    '
    nproto:
    '
    if (ascn<>123)and(ascn<>61) then
      n=18 'DECLARE ONLY
    else
      n=11
    end if
    inserts(s,w3,i)
    goto directdim 'ALL PROCEDURES
    '
  end if 'C declarations
  '
  'END INSTANTIATIONS
  '
  '
  end if 'FIRST WORD IN LINE nl=1
  '
  nl=0
  '
  '
  'QUALIFY FOR AUTODIM
  '-------------------
  '
  if ascn<>61 then goto nrelaxed
  if isa(ascw)=0 then goto nrelaxed
  '
  if (mp<>0)or(mc<0) then
    goto nrelaxed
  else
    if relaxed=0 then ers="not defined" : ert=42 : goto exitap
  end if
  '
  enlet:
  '=====
  '
  w3=ow
  if ascn=61 then i+=1 : nextinstruct(s,i)
  w2=dimtype(s,i)
  inserts(s,w2+" "+w3+cr+w3+"=",i)
  goto mainLoop


  nrelaxed:
  '========
  '
  '
  'PROCEDURE OR EXPRESSION
  '=======================
  '
  if varf>=8 then
    if ascn<>91 then w2="" : goto procs 'normal procedure (not an array of procedures)
  end if
  '
  if typ=0 then goto nassign  'SKIP ASSIGNMENT, NOT TYPED, JMP/CALL ...
  '
  '
  '
  '                    ####          ####
  '                    ##              ##
  'RESOLVED VARIABLES: ##  [reg+offs]  ##
  '                    ##              ##
  '                    ####          ####
  '
  '
  '
  'LEFT SIDE VARIABLE ASSIGNS
  '==========================
  '
  osg=owa
  psg=wpfx 'ASSIGNMENT OPERAND ADDRESS RESOLUTION
  wsg=wr   'ASSIGNMENT OPERAND
  '
  if ascn=61 then
    'ZSTRING / CHAR POINTER ASSIGN STRING
    'ASSIGN POINTER ONLY
    if iszstr(typm) then
      a=ind : if varf=1 then a=0
      if (a<>0)or(varf=3) then 'exclude direct string member
        addrtrim(psg)
        i+=1 : w2=pword(s,i) 'LOAD OPERAND
        if nisxn then ers="must be a string operand" : ert=800
        if ert then goto exitap
        w1=makestrptrfun(w2)+psg+"mov "+wsg+cm+w2+cr
        goto cleardown
      end if 'ptr
    end if 'iszstr
  elseif ascn=123 then
    goto leftside 'MULTIASSIGN
  else 'operand ascn<>61
    if nisxn then w3=wordahead(s,i) else w3="" : nwd=i
    if (asc(s,nwd)<>61)and(asc(s,nwd+1)<>61) then
      if typm then
        inserts(s,owa+" ",i) : typm=cpuw : op=0 : rps=0 : hiex="" : epfx=""
        w1=express(s,i,typm) 'naked statement
        goto cleardown
      end if
      'itr registers, commas etc pass thru
      goto addsrc
    end if
  end if
  '
  wr=tword(s,i) 'OPERATOR
  cpa=identopeq(s,i,w1) 'IDENTIFY OP
  nextinstruct(s,i)
  '
  '
  '      #
  '      #     ########
  '   #######
  '      #     ########
  '      # 
  '
  '
  'LEFT SIDE
  '=========
  leftside:
  '
  'CHECK FOR MULTIPLE ASSIGNMENTS
  'ARRAY ASSIGNMENTS & OBJECT ASSIGNMENTS
  '
  '<= => ={
  '
  if (ascw=60)or(ascn=62)or(ascn=123) then
    typ=typm
    mp=mq1
    w1=multiassign(s,i,typm)
    goto cleardown
  end if
  '
  'CREATE ASSIGNMENT CODE
  '
  if mp>0 then
    if cpoint then
      if typ>=htyp then
        typ=cpuw
        typm=cpuw
      end if
    end if
    '
    if typm<htyp then
      asg=psg+operi(2,typ,wsg) 'ASSIGNMENT FOR PRIMITIVE TYPES
      '
      'ASSIGNMENT PROCEDURE FOR DYNAMIC STRINGS
      if (typ>=&he0)and(typ<&h100) then
        w2=mid(macso(mp,1),3,3)
        if w2="bp-" then a=asstrla else a=asstrga 'LOCAL GC / GLOBAL GC
        asg+=rtlo(a)
      end if
    end if
  else
    'W1 CONTAINS ASM INSTRUCTION
    asg=psg+w1+wsg+cm+cpua+cr
  end if
  '
  if ert then goto exitap
  if iss(ascn) then
    w1=asg : goto cleardown 'NO RIGHT SIDE
  end if
  '
  '
  'RIGHT SIDE
  '==========
  '
  'SIMPLE INTEGER ASSIGNMENTS (OPTIMISATION)
  '
  if integerassign(s,i,typm,w1) then goto cleardown
  '
  '
  generalexp:
  '==========
  '
  if cpa>=71 then wr=w1
  if cpa>2 then inserts(s,osg+"="+osg+" "+wr+" ",i) : goto mainloop 'A+=B' TO:  'A = A + B'
  op=0
  if typm>=htyp then asg=""
  w1=express(s,i,typm)+asg
  if typm>=htyp then
    'EXPRESSIONS USING HIGHER TYPE OPERANDS
    'RPS
    a=findop(typm,"save",0)
    if a then
      hiex=sp+hiex+ep 'ASSIGN USING OP DEFINITIONS
    else
      if typm=typg then
        rps=16
        if opg<=1 then w1="" : w3="@"+owa else w3=qeax 
        hiex=storecode(w1)+cr+"copy @"+osg+cm+w3+cm+"sizeof "+typename(typm)+cr 'DEFAULT ASSIGN BY COPYING FROM VARIABLE
      else 'NOT A SIMPLE COPYING OPERATION
        ert=203 : ers="Unable to assign types "+sog+" to "+w2
      end if
    end if
    w1=""
  end if
  '
  goto cleardown
  '
  '
  nassign:
  '=======  
  '
  w2=""
  '
  'ASM CALL/JMP OR IMPLIED PROCEDURE
  '=================================
  '
  c=dic(" call 1, jmp 2, ",wr)
  if c then
    typ=0
    b=0
    w4=wr
    w2=wordahead(s,i)
    if w2="far" then
      m=i : endline(s,i)
      appendt(w4+" "+mid(s,m,i-m)+cr) 'CALL FAR / JMP FAR
      goto mainloop
    end if
    '
    if instrword(" fwd long short ",w2) then i=nwd else w2="" 'JMP FWD ...
    '
    'CHECK FOR CALL CALL..
    '
    nobr=1 'prevent '()' brackets being interpreted as array
    do
      wr=pword(s,i)
      if wr="call" then
        continue do
      else
        exit do
      end if
    loop
    nobr=0
    if isxn then
      if (mc>=-5)and(mc<=-4) then 'obtain vector
        c=4
        if ascw<>91 then
          w1=pword("@"+wr,1)
          if ascw=91 then
            wr=w1
          else
            wpfx=""
          end if
          skiplspace(s,i)
        end if
      end if
      'if (c=1)and(cpuw=8) then c=3 'STACK ALIGNMENT
      'if c=3 then appendt(enc("sp -8"))
      appendt(epfx+wpfx+w4+" "+w2+" "+wr+cr) 'itr calling basic proc (compact mode)
      'if c=3 then appendt(enc("sp 8"))
      epfx=""
      goto mainloop
    end if
    if varf<8 then varf=8
    w2="call "
    goto procs
  end if
  '
  '
  if varf<8 then goto nproc
  '
  '
  procs: 'ALL COMMAND LEVEL PROCEDURES
  '===================================
  '
  '
  w3=owa 'itr macros
  if mc=-16 then
    if wr="mid" then
      w3="_mid"
    end if
  end if
  '
  w4=""
  if ascn<>lbr then
    if nisxn then
      w4=" " : b=i
      if (ascn=45)or(ascn=38)or(ascn=64) then b+=1
      w5=wrd(s,b) : captarray(s,b) : skiplspace(s,b)
      if nisxn then '1st param is an expression or array
       w4="("+captsr(s,i)+")"
      end if
    end if
  end if
  inserts(s,w2+w3+w4,i)
  w1=express(s,i,0)
  if (typ>=&h40)and(typ<htyp) then
    ow=w3
    if ert=0 then
      ers="Must assign to a variable "
      ert=404
    end if
  end if
  '
  '
  cleardown:
  '=========
  '
  if ert then goto exitap
  '
  checkstringparam(typm)
  if ert then goto exitap
  jn=0   'clear string joining flag itr
  if dts>0 then
    w1+=rtl(deltmpa)
    dts=-1 'deleted temp strings
  end if
  '
  w1=epfx+w1
  '
  if rps then
    if len(w1) then
      hiex+=storecode(w1)+cr
    end if
    inserts(s,hiex,i)
    if len(shs) then shs+=cr+">>>>"+cr+hiex '#SHOW
    hiex="" : rps=0
  else
    appendt(w1) 'FULLY RESOLVED TO ASSEMBLY CODE
    'mct=0 'CLEAR RECURSION COUNTER
  end if
  '
  skiplspace(s,i)
  '
  cpa=0 : fpu=0 : nprec=0 : parx=0 : divi=0
  psg="" : asg="" : osg="" : epfx=""
  '
  goto mainloop
  '
  endings:
  '========
  '
  b=0
  select case md
  case 09 :           goto endpro   '          SUB
  case 10 :           goto endpro   '          FUNCTION
  case 11 :           goto endpro   '          METHOD
  case 34 :           goto endcons  '          NEXT
  case 13 : md=17   : goto endcons  'IF     to ENDIF
  case 21 : md=18   : goto endcons  'DO     to ENDDO
  case 23 : md=19   : goto endcons  'WHILE  to ENDWHILE
  case 29 : md=20   : goto endcons  'SELECT to ENDSEL / SWITCH TO ENDSEL
  case 37 : b=1                     '          METHODS
  case 41 : b=1                     '          BLOCK
  case 42 : b=1                     '          SCOPE
  case 48  'EXTERN
    ccx=0 : atx=0 : etx=0 : libr="" : goto mainloop
  case 00
  if wr="with" then
    wi=0 : wth="" : goto mainloop
  end if
  '
  end select
  '
  endline(s,i)
  '
  if b then 'METHODS ;BLOCK 'SCOPE
    '
    w1=ep
    '
    if md=37 then 'END CLASS
      '
      'INSERT TABLE BUILDING CODE ETC
      '------------------------------
      '
      if clsi then
        w2=macso(clsi,0)
        w1=macso(clsi,3)+ep+enc("xc "+w2)
        wr+=" of "+w2 'label for vew
        clsi=0
      else
        ert=107 : ers="Class not defined" : goto exitap
      end if
    end if
    '
    '
    if vew then
      if wr="}" then wr=""
      w1+="'END "+ucase(wr)+cr+cr
    end if
    '
    inserts(s,w1,i) ': unnest()
    goto mainloop
    '
  end if
  '
  ers="Invalid end: "+wr : ert=99 : ow="" : goto exitap
  '
  '
  endpro:
  '
  'PROCEDURE EPILOG
  '================
  '
  if atf then
    w2=restoreregs
    w3=""
  else
    w2=""
    w3=enc("xp ") 'XP TAG PROCEDURE END
  end if
  '
  w1=cr+"._end_proc"+cr+_
  retvalue()+_
  "._return_"+cr+_
  releaselocalbuffers()+_
  managelocalbase()+_
  w2+_ 'restoreregs
  returns()+ep+"._over_"+cr+w3
  appendt(w1)
  '
  if compact then
    '
    a=0
    w1=hexci(nsi)+" "+hexci(j) 
    'nsi=CURRENT NAMESPACE
    'j=POSITION FOLLOWING FUNCTION ENVELOPE
    if funn=13 then 'METHOD
      mp=clsi
      w2=fnam
      b=-1
      'locate header record to patch in list position
      do
        findmemb(w2,w4,b,m) 'ALSO ALTERS PLQ (PATCH POSITION)
        if b=0 then exit do 'fail
        w5=splitsi(sig,w3)
        if w5=fsig then exit do 'MATCHING PROTOTYPE
      loop
      if b then
        a=omacs+1
        a=maco(mp,a)+3+plq 'GET PATCH POSITION FOR PROCLIST RECORD POSITION
        fnam=macso(mp,0)+"."+fnam 'CLASS.METHOD
      end if
    else 'SUBS AND FUNCTIONS <>13
      a=funl
    end if
    '
    if a then
      w3=" "+fnam+fsig+" "
      mid(sps,a)=hexci(plistend) 'PATCH IN LOCATION OF PROCLIST RECORD
      if (atf<>0)or(flbl<>0) then
        w2="? "+fnam+" "+w1+cr+"?" 'PROCEDURE CANNOT BE DELETED
      else
        w2="!" '!' PROCEDURE CAN BE DELETED
      end if
      w2+=w3+w1+cr
      appendm(proclist,plistend,w2)
    end if
    '
  end if 'COMPACT
  '
  unnest()
  '
  'RESTORE LOCAL VARIABLE OFFSET
  '
  aoffl=scop(brc+1).aoffl
  if lclv then aoff=aoffl
  '
  nepilog:
  '=======
  '
  if ert then goto exitap
  funi=0
  ths=0
  goto mainloop
  'END OF PROCEDURE EPILOG
  '
  nproc:
  '=====
  '
  '
  '
  '##############################
  '
  '     #####    #####   #     #
  '    #     #  #     #  #     #
  '    #     #        #  #     #
  '    #     #   #####   #######
  '    #     #  #        #     #
  '    #     #  #        #     #
  '     #####   #######  #     #
  '
  '##############################


  if (mc<>-14) then goto end_o2h
  '
  '
  '
  '=======
  maino2h:
  '=======
  '
  'O2H KEYWORDS
  '
  md=maco(mp,5)
  '
  '
  n=0
  '
  select case md
  '
  case 2
    wr=pword(s,i) : goto enlet 'LET
'  case 3
'    '
'    'OPERATOR
'    '
'    'support multiple operator declarations
'    '
'    do
'      w1=noquotes(tword(s,i))
'      newrecord(w1)
'      maco(me,0)=-12
'      '
'      'SET PRECEDENCE LEVEL (WITH HIGH DEFAULT)
'      '
'      if nisxn then
'        a=wval(tword(s,i))
'      else
'        a=99 'HIGHEST PRECEDENCE
'      end if
'      '
'      maco(me,5)=a 'RECORD OPERATOR PRECEDENCE
'      '
'      addme : if ert then goto exitap
'      if ascn=44 then i+=1 : continue do 'MORE OPERATORS TO FOLLOW
'      exit do
'    loop
'    continue do
'    '
'    '
    '
    '
    '  ############################
    '
    '  #########   ###  ##       ##
    '   #       #   #   # #     # #
    '   #       #   #   #  #   #  #
    '   #       #   #   #   # #   #
    '   #       #   #   #    #    #
    '   #       #   #   #         #
    '  #########   ###  #         #
    '
    '  ############################
    '
    '
  case 4  : n=4  : 'DIM (GLOBAL/LOCAL)
    w1=wordahead(s,i)
    if w1="shared" then 'FREEBASIC DIM SHARED
      i=nwd : skiplspace(s,i)
      if funi then ers="Shared variables must be dimensioned outside procedure block" : ow="" : ert=200 : goto exitap
    elseif w1="static" then 'DIM STATIC
      i=nwd
      if funi then n=3
    end if
  case 5  : n=1  : 'LOCAL
  case 6 
    if funi then
      n=3 'STATIC STATIC VARIABLES IN PROCEDURES
    else
      'POSSIBLE STATIC IN C HEADER
      goto mainloop
    end if
  'case 7  : n=4  : if funi then ers="Globals must be outside procedure block" : ow="" : ert=200 : goto exitap
  case 8  : n=18 : 'DECLARE
  case 9  : n=11 : 'FUNCTION
  case 10 : n=12 : 'SUB
            if issub(s,i)=0 then goto addsrc 'assembler sub
  case 11 : n=13 : 'METHOD
  end select
  '
  w=swd 'SET BLANKOUT MARKER
  '
  '
  'DISTINGUISH FROM ASSEMBLER sub
  '
  '
  pf=0 'CLEAR FUNCTION POINTER FLAG
  '
  directdim:
  '=========
  '
  if clsi then
    if (n=11)or(n=12) then n=13 'TREAT AS METHOD
  end if
  '
  if n=0 then goto notdim

  'TRANSLATE DIM TO VAR AND INITIALISE
  '
  'clear dim state
  w1="" : w2="" : w4="" : w5="" : w6="" : w7="" : w8=""
  wt="" : wm="" : ws="" : sigs="" : sigd="@"
  q=0 : fdd=0 : pn=0 : typd=0 : typf=tys : df=0 : dg=0 : fc=0
  opa=0
  '
  if n>10 then
    'n=11,12,13,18
    wfn=ow
    prepareprocedurerecord() 'macro 'PREPARE FOR PROCEDURES
  else
    select case n
    case 1 : if funi=0 then ers="Locals must be inside a procedure block" : ow="" : ert=99 : goto exitap
    case 3 : if funi then w6=sq+cr : w7=eq+cr else n=4  'PROC STATICS ARE MARKED FOR TRANSFER
    case 4 : if funi then n=1 'DIM LOCAL
             if wr="const" then cnst=1
    end select
  end if 'N>10
  '
  '
  '
  '    #
  '  ##
  ' ##
  ' ##  PROCESS EACH DECLARATION PARAMETER
  ' ##
  '  ##
  '    #
  '
  ParseDim() 'macro
  if n<10 then continue do 'MAIN
  '
  '
  '  #
  '   ##
  '    ##
  '    ##
  '    ##
  '   ##
  '  #
  '
  b=-5 'DEFAULT METATYPE
  '
  ndimbr:
  '======
  '
   completeprocedurerecord() 'macro
  '
  funn=n
  fnam=wn
  fsig=sigs
  '
  '
  'PROCEDURE BODY FORMATS
  '======================
  '
  'SHORT FORM FUNCTION() AS TYPE =
  '===============================
  '
  assieq(s,i)
  if ascn=61 then
    i+=1 : m=i
    endcontline(s,i)
    w1="{ return "+mid(s,m,i-m)+" }"
    inserts(s,w1,i) : ascn=123
  end if
  '
  nextinstruct(s,i)
  '
  '
  'FUNCTION() AS TYPE (..)
  '=======================
  '
  '
  'POSSIBLE {..BODY..}
  '===================
  '
  funbr=cbrencah(s,i,n+1100)
  '
  if ert then goto exitap
  '      '
  'END PROCEDURE BODY FORMATS
  '
  'PROCEDURE PROLOG
  '================
  '
  w1=""
  w2="."+wn
  '
  if (atf<>0)or(flbl<>0) then
    w1+=w2+cr 'ADD PLAIN LABEL ABOVE
  end if
  '
  if n=13 then
    w2+=sigs
  else
    w2=w1+w2+sigs
  end if
  '
  '
  'UNUSED PROCEDURES REMOVAL (PASS 3)
  '
  if tranpass=3 then
    '
    if funn=13 then
      w1=" "+macso(clsi,0)+"."+wn+sigs+" " 'SIGNATURE INCLUDES CLASS NAME + DOT
    else
      w1=" "+wn+sigs+" " 'NORMAL PROCEDURE SIGNATURE
    end if
    '
    a=instr(plp,proclist,w1)
    if a then
      plp=a : endline(proclist,plp) : plp+=2 'NEXT PROCLIST RECORD
      if asc(proclist,a-1)=33 then
        'EXCLUDE BLOCK
        if funbr then inserts(s,"{",i) : wfn=""
        captprocbody(wfn,s,i,a) 'BYPASS PROCEDURE BODY
        if a then i=a
        'METHODS
        if funn=13 then
          'DELETE TABLE ENTRY IN CLASS HEADER
          w1=macso(clsi,3)
          a=instrevn(-1,w1,"|te "+wn+sigs+" ") 'FIND LATEST MATCH
          if a then
            b=a
            endline(w1,a)
            mid(sps,maco(clsi,omacs+3)+3+b)=space(a-b) 'BLANK TABLE ENTRY
          end if
        end if
        w1="" : goto nepilog
      end if ' EXCLUDED
    end if ' LOCATED
  end if 'TRANPASS 3 REMOVING PROCS
  if atf=0 then w3=enc("yp ") else w3="" 'YP TAG PROCEDURE START
  appendt(w6+w3+"jmp fwd _over_"+cr+enc("al 10")+w2+sp)
  nest()
  '
  if ert then goto exitap
  '
  mest=me 'LOCAL FENCE (SET BEFORE PARAMS AND LOCALS)
  '
  'GET PARAM OFFSET a
  '==================
  '
  a=2 'DEFAULT
  if atf then a+=4
  a*=cpuw
  retb=a
  '
  '
  'CHECK FOR 'THIS' IN METHODS
  '===========================
  '
  if clsi then
    w1=macso(clsi,0) 'get name of class
  end if
  if n=13 then
    if clsi=0 then
      ers="Unknown Class for "+ wn : ert=420 : goto exitap
    end if
    setthis(w1,a)
  else
    if clsi then
      ths=mest 'dummy enables access to static members 'itr virtual?
      vars(w1+"*this"+cr)
    end if
  end if
  '
  'SET UP PARAMS
  '=============
  '
  c=ccp 'CALLING CONVENTION
  '
  if (c<>16)and(c<>17) then
    vars("sys param at @"+memreg(qebp,a)+cr)     'generic param array
  end if
  '
  localvars()
  asce=1
  aoffl=a
  aoff=a
  '
  'ARGUMENTS
  if len(wva(2)) then
    '
    'CHECK CALLING CONVENTION REQUIREMENTS
    if c=8 then 'PASCAL PARAMS IN REVERSE ORDER
      w2=wva(2) : wva(2)=""
      c=1 : d=1
      do
        endline(w2,c)
        wva(2)=mid(w2,d,c-d)+cr+wva(2)
        c+=2 : d=c
        if d>len(w2) then exit do
      loop
    end if
    vars(wva(2))
    'lcl=1  'PARAMETERS
  end if
  '
  b=aoff-retb ' RETURN DUMPING N BYTES (STDCALL ETC)
  reto=b
  maco(mqf,1)=b
  '
  if atf then appendt(preserveregs) 'preserveregs()
  '
  prepforlocalspace(pn)
  '
  'nprocparams:
  '===========
  '
  wva(1)="" : wva(2)="" 'CLEAR LOCAL AND RETURN PARAMS
  '
  if len(insertc) then inserts(s,insertc+" "+qu+wn+qu+cr,i)
  '
  goto mainloop
  'END OF PROCEDURE PROLOG
  '
  '
  '======
  notdim:
  '======
  '
  'n=0
  '
  select case md
  '
  'RETURN C STYLE
  '==============
  '
  case 38
  '
  if funi then
    '
    if isxn then
      w1=cr 'NO RETURN PARAM GIVEN
      goto ncsreturn
    end if
    '
    typm=typp
    '
    select case typm
    case &h0               : typm=cpuw
    case &h40              : typm=&h68 'fpu type treated as double
    case &he0 to &hff      : typm-=32  'return bstring
    case htyp to 999999999 : typm=0    'force return of address
    end select
    '
    'THE RESULT IS LEFT IN THE ACCUM (CPU / FPU / SIMD )
    '
    op=0 : asg="" : c=0 : typ=0
    w3=wordahead(s,i) : b=nwd
    if isx(asc(s,nwd)) then
      if isq(asc(w3)) then
        w1=w3 'string literal
      else
        w1=mword(w3,1)
      end if
      if asc(w1)=91 then
        c=1
        if cpuw=8 then
          if (typ=typm)and(requiresimd(typ)<>0) then
            i=b
            c=2
          end if
        end if
      end if
    end if
    '
    if c=2 then
      w1=loadsimd(w1,typm)
      goto ncsreturn
    end if
    'RETURNING BSTRINGS - AVOID THE CAT, AND MEMORY LEAKS FROM UNFREED BSTR
    'RETURNING STRINGS BY TRANSFER (REMOVE FROM GC LIST)
    a=(typm-typ) and 31
    if (c=1)and(isdstr(typ))and(a=0) then
      if instr(w1,"[ebp-") then 'LOCAL STRINGS ONLY
        if typ<&he0 then
          w1=operi(1,cpuw,w1)  'RETURN BSTRING DIRECT
        else
          w1=medi+w1+cr+rtl(trbstra)  'TRANSFER STRING
        end if
        i=b
        goto ncsreturn
      end if
    end if
    w1=express(s,i,typm) 'TEMP STRINGS NOT DELETED LATER IN EPILOG
    if requiresimd(typm) then
      w1+=fputosimd(typm)
    elseif cpuw=4 then
      if (typm>=40)and(typm<&h4f) then
        w1+=cpuquad
      end if    
    end if
    '
    ncsreturn:
    '
    if ert then goto exitap
    if dts>0 then
      w1+=rtl(deltmpa)
      dts=-1 'deleted temp strings
    end if
    w1+="jmp fwd _return_"+cr
    goto cleardown
    '
  end if 'funi
  '
  '
  '------------------------------
  'CHECK FOR START OF INNER SCOPE
  '==============================
  '
  'BLOCK 41
  'SCOPE 42
  '
  case 41 to 42
  '
  nextinstruct(s,i)
  cbrencah(s,i,md+1000)
  if ert then goto exitap
  if ascn<>lbr then inserts(s,sp,i)
  goto mainloop
  '
  '
  case 25 'EXIT
  '
  b=swd
  c=0
  '
  if (isn(ascn)=0)and(nisxn) then
    wr=tword(s,i)
    c=dic(" function 1, sub 1, method 1, do 2, while 3, for 4, if 5, when 5, ", wr)
    select case c
    case 1 : wr="proc" 'function 'sub 'method
    case 2 : 'do
    case 3 : wr="do" 'while
    case 4 : 'for
    case 5 : 'if 'when
      w3=captsr(s,i)
      inserts(s,"if "+w3+exitdo,i)
      goto mainloop
    end select
  end if
  '
  if c then
    appendt("jmp fwd _end_"+wr+cr)
  else
    endline(s,i)
    appendt(mid(s,b,i-b)+cr)
  end if
  goto mainloop
  '
  '
  '
  '-------------
  'METHODS OF ..
  '=============
  '
  case 37
  '
  w1=tword(s,i)
  if w1="of" then w1=tword(s,i) 'SWALLOW `OF`
  mp=lookupm(w1)
  '
  '
  if mp=0 then ers="class/type not found: "+w1 : ert=11 : goto exitap
  if maco(mp,0)<>-3 then ers="not a class/type: "+w1 : ert=11 : goto exitap
  '
  if vew>0 then appendt(cr+cr+"'METHODS OF "+w1+cr)
  '
  'CAPTURE OR START SCOPE
  '
  cbrencah(s,i,md+1000) : if ert then goto exitap
  appendt(sp)           'support for static members in functions
  nest()
  if lclv then staticvars()     '
  clsi=mp : 'REMEMBER CLASS
  '
  goto mainloop
  '
  '
  '
  '   #########
  '  ###########
  ' ## CONTROL ##
  '  ###########
  '     ##
  '     ##
  '     ##
  '     ##
  '    ####
  '   ######
  '   ######
  '  ########
  '
  '
  '
  case 35 to 36 ' 'GOTO / 'GOSUB
  '
  w1=pword(s,i)
  if isn(ascw) then w1="_"+w1 'LINE NUMBERS
  'captsr(s,i)
  '
  if nisxn then
    a=dic(" if 1, when 1, while 1, until 2, ",wordahead(s,i))
    if a then
      w2=""
      if a=2 then w2="not "
      i=nwd
      w3=captsr(s,i)
      inserts(s,"if "+w2+w3+cr+wr+" "+w1+cr+"end if"+cr,i)
      goto mainloop
    end if
  end if
  '
  if md=35 then 'goto
    appendt(epfx+wpfx+"jmp "+w1+cr)
  else 'gosub
    'maintain stack alignment in 64 bit apps
    if cpuw=8 then appendt(enc("sp -8"))
    appendt(epfx+wpfx+"call "+w1+cr)
    if cpuw=8 then appendt(enc("sp 8"))
  end if
  epfx=""
  goto mainloop 'GOTO 'GOSUB
  '
  '
  case 13 'IF
  '
  n=1 : w1=sp : cnd=1
  '
  '
  case 21 'DO
  '
  if iss(ascn)=0 then 'DO SOMETHING ...
    if isb(ascn) then 'DO {...} WHILE (...)
      capturi(s,m,b,i) : w2="do"+cr+mid(s,m,b)+cr
      inserts(s,w2+"loop ",i)
      goto mainloop
    end if
    w2=wordahead(s,i)
    if w2="while" then goto mainloop
  end if
  n=2 : w1=sp+"._do"+cr
  '
  '
  case 23 'WHILE
  '
  nobr=123 : w3=captsr(s,i) : nobr=0
  if ascn=123 then i+=1 : w2="{" else w2=""
  inserts(s,"do"+w2+cr+"if not "+w3+exitdo,i)
  goto mainloop
  '
  '
  case 31 'FOR
  '
  n=4 : fro=1 : cnd=2 : w1=""
  '
  'strip any outer brackets
  '------------------------
  '
  if ascn=lbr then
    capture(s,m,i,a)
    mid(s,m)=" " : mid(s,i-1)=" "
    i=m : skiplspace(s,i)
    if sr2=59 then fro=2 'requires #semicolon separator on
  end if
  '
  '
  '-------
  'DEFAULT
  '=======
  '
  case 27
  '
  a=cas and 3 'CASE / SWITCH FLAG
  if a=1 then
    appendt("jmp fwd _end_sel"+cr+"._end_cas"+cr) 'SELECT
  elseif a=3 then
    appendt("._end_cas"+cr) 'SWITCH
  end if
  cas=0 : goto mainloop 'SAME AS 'CASE ELSE'
  '
  '
  '-----
  'BREAK
  '=====
  '
  case 28
  '
  if isxn then
    if slx then
      if cas>1 then appendt("jmp fwd _end_sel"+cr) 'select/switch break
      goto mainloop
    end if
    a=0
  else
    a=1
  end if
  if a then
    inserts(s,"exit ",i) ' do if when ...
  else
    appendt("jmp fwd _end_do"+cr) 'do break
  end if
  goto mainloop
  '
  '
  '---------------
  'SELECT / SWITCH
  '===============
  '
  case 29
  '
  slc(slx)=cas : sls(slx)=wc
  n=5 : op=1 : b=0
  if ascn=&h63 then
    if wordahead(s,i)="case" then i=nwd : skiplspace(s,i)
  end if
  if ascn=&h62 then
    if wordahead(s,i)="bit" then i=nwd : b=8 'bitwise testing
  end if
  wc=express(s,i,0)
  if isfloat(typg) then
    a=typg
  else
    a=4
    wc+=cvtai(typg,a)
  end if
  slt(slx)=a
  w1=sp+wc+cr
  typm=typg
  cas=b
  if wr="switch" then
    cas or=2 'C STYLE SWITCH
  end if
  nextinstruct(s,i)
  cbrencah(s,i,n)
  slx+=1
  '
  '
  '----
  'CASE
  '====
  '
  case 30
  '
  a=cas and 3 'CASE / SWITCH FLAG
  '
  '
  if a=1 then
    appendt("jmp fwd _end_sel"+cr+"._end_cas"+cr) 'SELECT
  elseif a=3 then
    appendt("._end_cas"+cr) 'SWITCH
  end if
  '
  '
  raltcase:
  '
  b=cas and 8 'BIT TESTING
  if b then
    c=80 'BIT TESTING
  else
    c=3  'COMPARING
  end if
  '
  if wordahead(s,i)="else" then
    i=nwd : skiplspace(s,i) : cas=0 : goto mainloop 'CASE ELSE (DEFAULT)
  end if
  '
  '
  'RELOAD REGISTER AFTER CASE (SWITCH ONLY)
  '
  w1=""
  if a=3 then 'after first switch case
    e=cas and 4
    if e=0 then
      w1=wc  'RELOAD QEAX REGISTER
    else
      cas xor= 4 'CLEAR RELOAD-INHIBIT
    end if
  end if
  '
  d=slt(slx-1) 'TYPE
  wr=SolveCaseSym(s,i,d,f,g) 'o2sema.bas
  if ert then goto exitap
  if f=2 then cas or= 4 'RELOAD INHIBIT
  w1+=wpfx+operi(c,d,wr)
  '
  '
  'ALTERNATIVE TESTING: CASE 10,13,32
  '==================================
  '
  w2=""
  '
  e=cas and 2 'TEST FOR 'SWITCH'
  if ((e=2)and(f=2))or(f=4) then
    b=b xor 8 'OPPOSITE LOGIC
    w3=" fwd _is_cas"
  else
    w3=" fwd _end_cas"
  end if
  '
  if f=4 then
    if b then
      if isfloat(d) then
        select case g
        case 0 : w4="jz"
        case 1 : w4="jb"
        case 2 : w4="jz"
        case 3 : w4="jbe"
        case 4 : w4="ja"
        case 5 : w4="jnz"
        case 6 : w4="jae"
        end select
      else
        select case g
        case 0 : w4="jz"
        case 1 : w4="jl"
        case 2 : w4="jz"
        case 3 : w4="jle"
        case 4 : w4="jg"
        case 5 : w4="jnz"
        case 6 : w4="jge"
        end select
      end if
      w3=w4+w3 'JZ CASE MATCH
    else 'BIT LOGIC ONLY
      w3="jnz"+w3  'JNZ CASE MATCH
    end if
    appendt(w1+w3+cr)
    goto raltcase
  end if
  '
  if f=3 then 'TO
    '
    'RANGE TESTING: CASE 1 TO 32
    '===========================
    ' 
    w3=" fwd _end_cas"
    i=nwd
    c=0
    skiplspace(s,i)
    if ascn=60 then '<
      i+=1
      skiplspace(s,i)
      c=1 'BOUNDARY FLAG
    end if
    wr=SolveCaseSym(s,i,d,f,g) 'o2sema.bas
    if f=2 then cas or= 4 'RELOAD INHIBIT
    e=cas and 2
    if (f=4)or((e=2)and(f=2)) then
      w2="jmp fwd _is_cas"+cr
    else
      w2=""
    end if
    '
    if isfloat(d) then
      w4="jb" 'BELOW
      w5="ja" 'ABOVE
    else
      w4="jl" 'LESS
      w5="jg" 'GREATER
    end if
    if c then
      w5+="e" 'JUMP ABOVE OR EQUAL: CASE 1.0 TO < 2.0
    end if
    w1+=w4+w3+cr+wpfx+_
    operi(3,d,wr)+_
    w5+w3+cr+w2 'CASE X TO Y
    if f=4 then 'COMMA
      w1+="._end_cas"+cr
      appendt(w1)
      goto raltcase 'MORE CASE EXPRESSIONS
    end if
    '
  elseif b then
    '
    'BIT TESTING
    '===========
    '
    w1+="jz"+w3+cr  'JZ BIT TESTING
    '
  else
    '
    'COMPARING
    '=========
    '
    if isfloat(d) then
      select case g
      case 0 : w4="jnz"
      case 1 : w4="jae"
      case 2 : w4="jnz"
      case 3 : w4="ja"
      case 4 : w4="jbe"
      case 5 : w4="jz"
      case 6 : w4="jb"
      end select
    else
      select case g
      case 0 : w4="jnz"
      case 1 : w4="jge"
      case 2 : w4="jnz"
      case 3 : w4="jg"
      case 4 : w4="jle"
      case 5 : w4="jz"
      case 6 : w4="jl"
      end select
    end if
    w1+=w4+w3+cr
    '
  end if
  '
  e=cas or 18
  '
  'NEXT CASE FOLLOWS IMMEDIATELY?
  '
  if e then 'SWITCH OR ALTERNATIVES
    e=cas and 2 'SWITCH
    if (e=0)or(f<>2) then
      w1+="._is_cas"+cr
    end if
    skiplspace(s,i)
  end if
  cas or=1
  goto xcnd
  '
  '
  '
  case 26 'CONTINUE / 'REDO / 'REPEAT
  '
  b=iss(ascn) 'end of statement
  if b then
    if wr="repeat" then appendt wr+cr : goto mainloop 'asm
    w1="do"+cr 'continue do
    w3=""
  else
    w1=tword(s,i)
    w3=captsr(s,i)
  end if
  a=dic(" while 1, when 2, until 3, for 4, do 5, if 6, ",w1)
  if asc(w3)>64 then 'EXPRESSION FOLLOWS
    b=0
    w2="if "
    select case a
    case 1 : b=1 'while
    case 2 : b=1 'when
    case 3 : b=1 : w2="if not " 'until
    case 6 : b=1 'if
    end select
    if b then
      inserts(s,w2+w3+contdo,i)
      goto mainloop
    end if
  end if
  w2="jmp long _do"
  select case a
  case 1 : 'while
  case 4 : w2="jmp fwd _step" 'for
  case 5 : 'do
  case else
    w2="repeat "+w3 'asm
  end select
  appendt(w2+cr) : goto mainloop
  '
  end select 'md
  '=============
  '
  '
  '
  '===========
  allcontrols:
  '===========
  '
  if n then
    '
    '
    if len(w1) then
      appendt(epfx+w1) : epfx=""
    end if
    '
    if n>0 then 
      if nsl>=99 then
        ert=300 : ers="too many block nestings "+wr : goto exitap
      end if
      ctb(nsl)=n
      a=i
      endline(s,a)
      cln(nsl)=lnmks+": "+mid(s,swd,a-swd)
      nsl+=1
      skiplspace(s,i)
    end if
    '
    if cnd=0 then goto mainloop
    '
    '
    if fro then
      iterationspec() 'macro
      goto cleardown
    end if 'FRO: FOR TO NEXT STATEMENTS
    '
    if ctb(nsl-1)=1 then
      w3=" fwd _end_cnd"+cr
    else
      w3=" fwd _end_do"+cr
    end if
    '
    w4=""
    '
    '========
    jumpcond: 'w3 jump to 'set cnd sense 'ALSO W4 SET
    '========
    '
    ctal=0
    '
    do
      wr=pword(s,i)
      if ascw=&h6e then
        if wr="not" then cnd=-cnd : continue do
      end if
      exit do
    loop
    '
    if cnd<0 then w2="jnz " else w2="jz "
    '
    if isendofexpress(s,i)=0 then goto condexpression
    if (varf>=8)or(typ>=htyp)or(rps) then goto condexpression
    '
    if ascn=&h74 then
      if wordahead(s,i)="then" then
        i=nwd 'skip
        if isn(asc(s,i)) then inserts(s,"goto ",i)
      end if
    end if 'single word conditional
    '
    w1=""
    '
    'check for numeric literal 'IF 1 IF NOT 0
    if wval(wr)<>0 then
      if cnd<0 then cnd=0 else goto xcnd
    elseif asc(wr)<=48 then
      if cnd<0 then goto xcnd else cnd=0
    end if
    '
    if cnd then
      w1+=wpfx+operi(&h20,typ,wr)
    else
      w2="jmp "
    end if
    '
    goto ccnd
    '
    condexpression:
    '==============
    '
    op=0 : parx=1024 : skiplspace(s,i)
    if isw(ascn) then owa+=" "
    inserts(s,owa,i)
    w1=express(s,i,0)
    '
    if ascn=&h74 then 
      if wordahead(s,i)="then" then
        i=nwd
        if isn(asc(s,i)) then inserts(s,"goto ",i)
      end if
    end if
    '
    if rps then
      w5="" : w3=""
     if n>0 then
        nsl-=1
        j=instrevn(j-1,t,"(") 'REMOVE NESTING FROM BUFFER
      end if
      select case n
      case -1 : 'ELSEIF
        if cnd=1 then
          w5="jz fwd _end_cnd"
        else 'ELSEIF NOT
          w5="jnz fwd _end_cnd"
        end if
        w3="or eax,eax"+cr+w5
      case  1 : 'IF
        if cnd=1 then
          w3="if eax" 'IF
        else
          w3="if not eax"
        end if
        w3+=" then "
      'case  3 : w4="while 1"+cr 'WHILE
      '  if cnd=1 then
      '    w5="jz fwd _end_do"
      '  else 'WHILE NOT
      '    w5="jnz fwd _end_do"
      '  end if
      '  w3="or eax,eax"+cr+w5
      end select
      a=i : endline(s,i) : w3+=mid(s,a,i-a)+cr
      hiex=hiex+epfx+w1+w3
      cnd=0 : epfx="" : w1=""
      goto cleardown
    end if 'rps
    '
    'ACTION FOLLOWING CONDITIONAL EXPRESSION
    '
    if ctal=-16 then
      w2="" : goto ccnd
    end if
    'OTHERWISE NO OPTIMISATION
    if isfloat(typg) then w1+=cvtai(typg,cpuw)
    '
    w1+="._cnd"+cr
    '
    if dts>0 then
      w1+=rtl(deltmpa) 'this must go here before conditional branching
      dts=-1 'DONE TEMP STRING DELETION
    end if
    '
    if ((opg<>33)and(opg<>34))or(dts=-1) then 'LOGIC OUTCOME FOR EAX
      w1+=boolcnd 'OR EAX,EAX
    end if
    '
    ccnd:
    '====
    '
    w1+=w2+w3+w4 'SKIP IF TRUE / IF FALSE
    '
    xcnd:
    '====
    '
    cnd=0
    ctal=0
    '
    skiplspace(s,i)
    a=0
    select case ascn
    case sr1  : a=1 : i+=1
    case sr2  : a=1 : i+=1
    case &h65 : if wordahead(s,i)="end" then a=2
    end select
    if a then
      inserts(s,cr,i)
      ascn=13
      d=1
    else
      d=ise(ascn)
    end if
    '
    if md=18 then nsl-=1 : goto cleardown 'DO {..} WHILE ..
    '
    'DETECT IMPLICIT ENDIF AT END OF LINE
    '====================================
    '
    if nsl then
      c=ctb(nsl-1)
      b=cbrencah(s,i,c)
      if (b=0)and(c=1)and(d=0) then
        sln+=1
      end if
    end if
    if d then
      endline(s,i)
    end if
    '
    goto cleardown
    '
    '
  end if 'all controls



  '
  endcons: 'ENDDO ENDWHILE 'WEND
  '=============================
  '
  '
  skiplspace(s,i)
  n=0 : cnd=0
  '
  select case md
  '
  case 18 'ENDDO
  '
  'do {...} while ...
  b=i
  skipspace(s,i) 'must be continuity (no basic comments etc)
  if (ascw=125)and(wordahead(s,i)="while") then
    i=nwd : skiplspace(s,i)
    w3=" long _do"
    w4="._end_do"+ep
    cnd=-1
    goto jumpcond
  else
    i=b : skiplspace(s,i)
  end if
  n=2 : appendt(exdo)
  '
  '
  case 19 'ENDWHILE
  '
  n=2 : appendt(exdo)
  '
  '
  case 12 'LOOP
  '
  if isw(ascn) then
    a=dic(" if 1, while 1, when 1, until 2, ",wordahead(s,i))
    if a then
      i=nwd
      w3=captsr(s,i)
      if a=1 then w2="if not " else w2="if "
      inserts(s,w2+w3+exitdo+"end do"+cr,i)
    else
      m=i : endline(s,i)
      appendt "loop "+mid(s,m,i-m)+cr 'POSSIBLE ASM BRANCH
    end if
    goto mainloop
  end if
  n=2 : appendt(exdo)
  '  
  case 24 'WEND
  '
  n=2 : appendt(exdo)
  '
  '
  case 34 'NEXT
  '
  nx-=1
  if nx<0 then ert=10 : ers="Too many nexts" : goto exitap
  if ascw<>125 then
    if iss(ascn)=0 then w2=tword(s,i) ' swallow iterator name: next i
  end if
  n=4 : appendt("._step"+cr+nxs(nx)+exnx)
  '
  '
  case 20 'ENDSEL / END SELECT / END SWITCH
  '
  slx-=1
  if slx<0 then ert=11 : ers="Too many end selects" : goto exitap
  n=5 : appendt(exsl)
  wc=sls(slx) : cas=slc(slx) 'up select level
  '
  '
  case 15 'ELSE
  '
  if ise(ascn)=0 then
    w1=wordahead(s,i)
    'ELSE IF
    if w1="if" then
      md=16 : i=nwd : skiplspace(s,i)
      if hei(nsl-1)=0 then appendt(exei) 'OTHERWISE SUPPRESS
      hei(nsl-1)=0
      cnd=1 : n=-1 : w1=""
      goto allcontrols 'treat as 'if'
    end if
  end if
  ' 
  b=i : nextinstruct(s,b)
  '
  if ascn=123 then
    cbrk(cbri)=1 : cbri+=1 : i=b+1
  else
    skiplspace(s,i)
  end if
  '
  appendt(exel)
  goto mainloop
  '
  '
  case 16 'ELSEIF
  '
  cnd=1 : n=-1 : w1=""
  '"jmp fwd _end_if"+cr+"._end_cnd"+cr
  if hei(nsl-1)=0 then appendt(exei) 'OTHERWISE SUPPRESS
  hei(nsl-1)=0
  goto allcontrols 'treat as 'if'
  '
  case 17 'END IF
  '
  n=1 : appendt(exif)
  if sln then sln-=1 'SINGLE LINERS DECR NESTING
  '
  case else
  '
  goto nendcons
  '
  end select
  '
  '===================
  'ALL CONTROL ENDINGS
  '===================
  '
  'ERROR CHECKS
  '
  if nsl<1 then
    ert=300 : ers="nesting error " : w1=" (no beginning)" : m=n
  else
    nsl-=1 : m=ctb(nsl)
    if m=n then goto mainloop 'OKAY
    ert=301 : w1=" expected"+cr+cln(nsl)
  end if
  '
  select case m
  case 1 : ers+="`end if`"
  case 2 : ers+="`end do` "
  case 3 : ers+="`end while` or `wend` "
  case 4 : ers+="`next`"
  case 5 : ers+="`end select`"
  end select
  '
  ers+=w1+cr : goto exitap
  '
  nendcons:
  '========
  '
  '
  'O2H DIRECTIVES
  '
  select case md
  '
  case 44 : wordeval(s,i,i) : ixb=dv  : goto mainloop       'INDEXBASE '#INDEXBASE (supports negative and positive)
  '
  case 45 :
            if isq(ascn) then
              if asc(s,i+1)=ascn then 'EMPTY QUOTE
                libr=""
                if atx=1 then atx=0
                i+=2 : goto mainloop
              end if
            end if
            atx or=1
            libr=rootpath(lpath+lexiword(s,i)) 'LIBRARY
            goto mainloop
  case 53 : nprec=1                   : goto mainloop       '#NOPREC (transient)
  '
  case 55 : bref=0                    : goto mainloop       '#BYVAL by default
  '
  case 56 : bref=1                    : goto mainloop       '#BYREF by default
  '
  case 60 : readstates(tword(s,i))    : goto mainloop       'READSTATE
  '
  case 62 : typo=17                   : goto declarations2  'DEFF
  '
  'case 63 : opers=lcase(mword(s,i))   : goto mainloop       'OPERATIONS
  '
  case 57 : '#DIM default type
  if isxn then
    tys=0
  else
    tys=identype(tword(s,i))
  end if
  goto mainloop
  '
  case 48  'EXTERN
  '
  if nisxn then
    w1=wordahead(s,i)
    a=identype(w1)
    if a then goto mainloop 'extern int xyz(...
  end if
  '
  ccx=0 : atx=1 : etx=0 : libr=""
  do
    w1=wordahead(s,i)
    a=dic(callco,w1)
    if a then
      i=nwd : ccx=a and &hff : continue do         'SET DEFAULT CALLING CONVENTION
    elseif instrword(" lib library ",w1) then
      i=nwd
      libr=rootpath(lpath+lexiword(s,i)) 'SET DEFAULT LIBRARY
      continue do
    elseif w1="export" then
      i=nwd : etx=1 : continue do               'SET PROCEDURES FOR EXPORT
    elseif instrword(" pure virtual com ",w1) then
      i=nwd : atx or=2 : continue do            'SET CLASSES / METHODS AS VIRTUAL
    elseif w1="preset" then
      i=nwd : atx or=4 : continue do            'SET CLASS TABLE POINTER AS PRESET EXPLICITLY 
    end if
    exit do
  loop
  goto mainloop
  '
  case 54 '#NOINIT FLAG FOR LOCAL VARS
  '
  yesno(s,i,noin) : goto mainloop 

  case 58 '#ASSIGN FLAG FOR C TYPE ASSIGNMENT OPERATOR (MUST US == FOR EQUALITY TEST)
  '
  yesno(s,i,casg) : goto mainloop 
  '
  case 59 '#INSERT
  '
  insertc=rtrim(captsr(s,i)) : clcase(insertc) : goto mainloop
  '
  end select
  '
  '
  end_o2h:
  '=======
  '
  '
  if mc<>-13 then nl=0 : goto addsrc
  '
  '
  '
  '#######################
  '
  '#######################
  '
  '     #####    ##### 
  '    #     #  #     #
  '    #     #        #
  '    #     #   ##### 
  '    #     #  #
  '    #     #  # 
  '     #####   #####O2
  '
  '######################
  '
  '#######################
  '
  '
  maino2:
  '======
  '
  '
  a=ascw
  '
  if mc=-13 then md=maco(mp,5) else md=0
  '
  select case md 'mc=13
  '
  case 1 : incli=1 : continue do 'INCL
  '
  case 4 'RETN
  '
  if reto then w1="ret "+str(reto) else w1="ret"
  appendt(w1+cr) : goto mainloop
  '
  '
  'case 6 'SKIP
  '
  '
  ' wont be passed to assembler single line or multi line (...)
  '
  'capturi(s,m,b,i) : if ert then goto exitap
  'skiplspace(s,i) : goto mainloop
  '
  '
  case 7 'WITH
  '
  wth=captsr(s,i)
  wi=len(wth)
  goto mainloop
  '
  '
  case 8 '
  '
  case 9 '
  '
  case 10 'O2 inline code
  '
  ws=wr+sp+captureblock(s,i,wr)+ep+asg : asg=""
  appendt(ws)
  goto mainloop
  '
  case 12 'BIND
  '
  wr=tword(s,i)
  if asc(s,i)=44 then i+=1 ' swallow comma
  nextinstruct(s,i)
  wd=captureblock(s,i,"bind")
  nocomments(wd)
  procaddrc(wd,wr)
  inserts(s,wd,i)
  goto mainloop
  '
  '
  'DECLARATIONS
  '============
  '
  case 14 : 'ENUM (bit) aa (n) bb cc
  '
  'check for function return: ENUM NN FN()
  a=i
  if ascn<>123 then
    w1=wrd(s,i)
    if w1="bit" then w1=wrd(s,i)
    if iss(ascn)=0 then
      b=i : nextinstruct(s,i)
      if ascn<>123 then
        i=b : inserts(s,"sys ",i)
        goto mainloop
      end if
    end if
  end if
  i=a : enums(s,i)
  if ert then goto exitap
  goto mainloop
  '
  '
  case 17 'VAR
  '
  b=i
  endline(s,i)
  wr=mid(s,b,i-b)
  nocomments(wr)
  varsal(wr) : if ert then goto exitap else goto mainloop       
  '
  case 11 : 'STRUCT C STYLE
  '
  'check for function return: STRUCT ST* FN()
  w1=wordahead(s,i)
  if asc(s,nwd)=42 then
    i=nwd+1
    inserts(s,"sys ",i)
    goto mainloop
  end if
  typo=2  : un=8
  '
  case 13   : typo=2  : un=16                   'CLASS
  case 15   : typo=18                           'DEF #DEF
  case 16   : typo=2                            'TYPE
  case 21   : pakd=1  : nl=1 : continue do      'PACKED
  case 22   : typo=19 :                         '_DEF (terminator def)
  case 23   : SetNameSpace(s,i) : goto mainloop 'NAMESPACE
  case 37   : typo=2                            'TYPEDEF
  case 38   : typo=2  : un=1                    'UNION
  case else : goto ntypo                        'NOT A TYPE / STRUCTURE
  '
  end select
  '
  declarations2:
  '=============  
  '
  '
  '  macs 0 name
  '  macs 1 prepared macro / resolved structure for types
  '  macs 2 offset and array spec for vars / array spec for typedefs
  '  macs 3 vf table building code
  '  maco 0 structure flag -3  ( -18 def -33 enum -3 type)
  '  maco 1 length
  '  maco 2 var offset / vtp spec for types
  '  maco 3 number of params in macro (metatype -18)
  '  maco 4 size of associated class vf table / var to be used in signature (1)
  '  maco 5 type code for vars
  '
  if typo then
    '
    m=swd
    '
    w1=wr ' TYPEDEF etc
    '
    wr=tword(s,i) 'COULD BE UNION STRUCT ENUM etc
    '
    if md<>37 then goto isdefi
    '
    'TYPEDEF ..
    '==========
    '
    'STRUCT?
    '
    a=dic(" union 1, struct 8,",wr)
    if a then
      un or=8 'FLAGS
      tdst=1 : nextinstruct(s,i)
      indt=0
      if ascn=123 then
        wr="anon" 'ANON STRUCTURE
      else
        wr=tword(s,i) 'NAMED STRUCTURE
      end if
      nextinstruct(s,i)
      if ascn<>123 then
        a=i
        if ascn=42 then i+=1
        skiplspace(s,i)
        if ascn=lbr then 'TYPEDEF STRUCT ST* (..)(..)
          inserts(s,"typedef sys",i)
          goto mainloop 
        end if
        'TYPEDEF STRUCT ST
        b=-1
        indt=0
        wn="void"
        i=a
        skiplspace(s,i)
        goto rtypedef
      else
        goto isdefi 'TYPEDEF STRUCT ST { ..}
      end if
    elseif wr="enum" then 'TYPEDEF ENUM ..
      a=i
      nextinstruct(s,i)
      if ascn<>123 then
        wr=wrd(s,i) : if wr="bit" then wr=wrd(s,i)
        b=i
        nextinstruct(s,i)
        if ascn<>123 then  'TYPEDEF ENUM NN (..)(..)
          i=b : inserts(s,"typedef sys ",i)
          goto mainloop 
        end if
      end if
      i=a : enums(s,i) 'TYPEDEF ENUM EN {..}
      if ert then goto exitap
      b=me-1 : wn=macso(b,0)
      b+=htyp
      goto rtypedef
    elseif wr="const" then
      wr=tword(s,i) 'IGNORE CONST
    end if
    '
    '
    'TYPEDEFS
    '========
    '
    'STRUCT ALREADY DEFINED?
    '
    i=swd
    tyd=1
    wr=mword(s,i)  'SUPPORTS MACROS
    tyd=0
    b=identype(wr)
    '
    '
    'CHECK WHETHER DEFINING A POINTERED FUNCTION
    '-------------------------------------------
    '
    'THE TYPE COULD BE ANOTHER TYPEDEF TYPE OR A 'C' TYPE
    'eg: typedef int (*getxyz)(int n)
    'eg: typedef xyz* (blah blah *getxyz)(int n)
    '
    if b then
      a=i
      do
        if ascn=42 then
          i+=1
          skiplspace(s,i) 'itr function returning a pointer to a float?
        else
          exit do
        end if
      loop
      '
      'EXTRACT FUNCTION NAME FROM WITHIN BRACKETS
      '
      if ascn=lbr then
        wr+=mid(s,swd+lenw,i-swd-lenw) 'INCLUDES PREVIOUS '*'
        i+=1
        ascw=0
        do
          d=ascw
          skiplspace(s,i)
          if ascn=lbr then
            capture(s,m,i,0) : ascw=0 : continue do 'INNER BRACKETS
          end if
          w1=tword(s,i) 'POSSIBLE FUNCTION NAME
          'if (d=42)and(ascn=41) then
          if ascn=rbr then
            i+=1
            nextinstruct(s,i)
            if d=42 then d=-2 else d=-1
            exit do
          end if
          if isx(ascn) then exit do
        loop
        if ascn<>lbr then
          w2=mword(s,i)            'RESOLVE ANY MACRO
          i=swd
          ascn=ascw
        end if
        if ascn=lbr then
          capture(s,m,i,0)         'ENCOMPASS PROTOTYPE
          macoin me                'INIT RECORD
          maco(me,0)=-8            'INDICATE TYPEDEF
          maco(me,1)=cpuw          'LENGTH OF POINTER
          maco(me,3)=0             'INDIRECTION
          maco(me,4)=-5            'INDICATE PROCEDURE POINTER
          maco(me,5)=b             'RETURN TYPE
          macsi(w1,me,0)           'TYPEDEF NAME AS FUNCTION NAME
          macsi(wr,me,1)           'RETURN TYPE AND '*'..
          macsi(mid(s,m,i-m),me,3) 'CAPTURE FULL PROTOTYPE
          addm() : addme           'STORE RECORD
          if ert then goto exitap
          goto mainloop
        end if
        ers="unknown construct" : ert=68 : goto exitap
      end if 'procedures typ (..)
    else 'unidentified type b=0
      ers="unknown type" : ert=69 : goto exitap
    end if
    '
    i=a  'REVERT TO PRIOR POSITION
    skiplspace(s,i)
    wn=wr
    goto rtypedef
    '
    '
    '======
    isdefi:  'COMING FROM:  typedef struct or equates % $ 
    '======
    '
    newrecord(wr)
    if ert then goto exitap
    '
    lbw=wr
    w5=""
    '
    'CAPTURE NEXT LINE NUMBER FOR POSSIBLE CLASS METHODS BLOCK
    '
    if md=13 then
      b=i : endline(s,b)
      b=instr(b+2,s,chr(39)+chr(lnm))
      if b then
        c=b : endline(s,c) : w5=mid(s,b,c-b+2)
      end if
    elseif md=11 then
      if ascn=59 then
        wr=""
        goto nblock 'EMPTY STRUCT C STYLE
      end if
    end if
    '
    'CAPTURE BODY
    '
    wr=captureblock(s,i,w1)
    '
    'CLASS/TYPE DEFINITION ON SINGLE LINE
    '
    if instr(wr,cr)=0 then
      nocomments(wr)
      replacewd(wr,":",cr,0)
    end if
    '
    w3=""
    if md<>13 then goto nblock
    if (atx and 2) then goto mclass 'VIRTUAL OR PURE
    '
    'SEPARATE TYPE AND METHODS WITHIN CLASS ENVELOPE
    maco(me,0)=-3 'to identify self as a type
    me+=1         'protect class record
    makeheaders(wr,w4,w3,2) 'mode 2 for class headers
    me-=1 'expose class record
    '
    '
    'COMPOSE VIRTUAL SECTION AND MAIN BODY
    '
    if len(w4) then
      wr=w4+cr+"/\"+cr+wr
    else
      vtlcheckmark(wr)
    end if
    '
    w1=macso(me,0)
    '
    mclass:
    '======
    '
    if atx then
      if instr(wr,"/\"+cr)=0 then
        if atx and 2 then
          wr+="/\"+cr 'VIRTUAL
        else
          wr="/\"+cr+wr 'EXTERN OR TABLE PRESET
        end if
      end if
    end if
    '
    'END CLASS HEADER
    '
    '
    '======
    nblock:
    '======
    '
    striplineno(wr)
    nocomments(wr)
    '
    if typo=18 then 'DEF '#DEF
      nofinalcr(wr)
    end if
    '
    macsi(wr,me,1) 'MACRO BODY
    '
    if (typo=17)or(typo=18)or(typo=19) then 'MACROS
      maco(me,0)=-typo 'METATYPE
      if typo=17 then maco(me,5)=&h6a 'extended floating point
      addme : if ert then goto exitap
      goto mainloop
    end if
    '
    incli=0
    '
    if typo<>2 then goto ntypo
    '
    types(un,atx,ttc,tuc) 'RESOLVE TYPE STRUCTURE
    '
    'CLASSES
    'COMPOSE METHODS BLOCK AND INSERT BACK INTO SOURCE STREAM
    'the methods block is needed even if it is empty
    'itr functions have access to static members only /callback functions
    '
    if md=13 then
      if (tuc>0)and(ttc=0)and((atx and 2)=0) then
        if w3="" then w3=cr 'trigger empty methods block
      end if
      if len(w3) then
        w3=cr+"methods "+w1+cr+w5+w3+cr+"end methods"+cr+cr
        inserts(s,w3,i)
      end if
    end if
    '
    pakd=0
    '
    if ert then goto exitap
    '
    'TYPEDEF STRUCTS (-8)
    '--------------------
    '
    skiplspace(s,i)
    '
    if isxn then goto typesdone
    '
    b=me-1
    lent=maco(b,1)
    wn=macso(b,0)
    b+=htyp
    indt=0
    if tdst=0 then
      goto typesdone
    end if
    '
    'NAME OF TYPE
    '
    '
    rtypedef: 'LOOP FOR EACH TYPE
    '========
    '
   'TYPES FROM TYPEDEF
   '==================
   '
    c=indt 'b carries index to the type
    '
    do
      wr=tword(s,i)
      '
      'INDIRECT TYPES
      '
      if ascw=42 then c+=1 : continue do
      '
      'IGNORE SELF-DEFINITION (sometimes due to case insensitivity: typedef long LONG)
      '
      if nisxn then
        i=swd
        wr=mword(s,i) 'POSSIBLE MACRO
      end if
      '
      if wr=wn then
        if ascn=44 then i+=1 : continue do
        goto typesdone
      end if
      '
      exit do
    loop
    '
    'ARRAY TYPES
    'FUNCTION POINTERS
    '
    w2=""
    '
    do
      if (ascn=lbr)or(ascn=91) then
        capture(s,m,i,a) : w2+=mid(s,m,i-m)
        skiplspace(s,i) : continue do
      end if
      exit do
    loop
    '
    macsi(w2,me,2) 'FUNCTION PROTOTYPE / ARRAY
    '
    if ascn=95 then
      w1=wordahead(s,i)
      '
      'ATTRIBUTE STUB
      '
      'itr macros
      '
      if w1="__attribute__" then
        i=nwd : capture(s,m,i,a) : skiplspace(s,i)
      end if
    end if
    '
    newrecord(wr)
    maco(me,0)=-8      'SIGNAL INDIRECT TYPE
    maco(me,1)=lent    'SIZE
    maco(me,3)=c       'INDIRECTION
    maco(me,4)=b       'UDT OR PRIMITIVE / POINTER
    addme
    if ert then goto exitap
    '
    if ascn=44 then
      i+=1
      nextinstruct(s,i)
      goto rtypedef
    end if
    '
    'itr semicolons: treat as linebreaks
    'itr #define on next line requiring contin
    '
    '
    typesdone:
    '=========
    '
    'RESUME MAIN PREP LOOP
    '
    tdst=0 : un=0
    '
    '
    'INSERT STRAY #DEFINES
    '---------------------
    '
    if len(defbuf) then
      inserts(s,defbuf,i) : defbuf=""
    end if
    w1=""
    goto cleardown
    '
  end if ' end defs
  '
  ntypo: 'end of types
  '=====
  '
  select case md
  '
  '
  case 18 'INCLUDE '#INCLUDE
  '
  includefile(s,i)
  if ert then goto exitap
  goto mainloop
  '
  case 2 '#SEMICOLON
  '
  w1=""
  if ise(ascn)=0 then w1=tword(s,i)
  if w1="comment" then sr2=58 : ct2=59 else sr2=59 : ct2=39
  goto mainloop
  '
  case 30 : paths(s,i,ipath)             : goto mainloop 'INCLUDEPATH
  case 31 : paths(s,i,lpath)             : goto mainloop 'LIBRARYPATH
  case 26 : endline(s,i) : appendt(cr)   : goto mainloop 'REM
  case 48 : endline(s,i) : appendt(cr)   : goto mainloop '#PRAGMA
  case 44 : yesno(s,i,relaxed)           : goto mainloop '#AUTODIM
  case 49 : yesno(s,i,uniq)              : goto mainloop '#UNIQUE
  case 50 : cnsl=1                       : goto mainloop '#CONSOLE
  '
  case 46 to 47   '#ALERT '#ERROR
  '
  ers=captureblock(s,i,wr) : ert=md-45 : ow="" : goto exitap
  '
  case 43 '#LOOKAHEAD
  '
  MakeHeaders(mid(s,i),w1,"",1)
  inserts(s,w1,i)
  if ert then goto exitap
  goto mainloop
  '
  case 51 '#SHOW
  '
  if ascn=34 then
    shf=lexiword(s,i)
  end if
  if tranpass=2 then
    bj=j 'mark Output code position
    shs=captsr(s,i)
    w1=shs+cr+she
    inserts(s,w1,i)
  else
    shf=""
  end if
  goto mainloop
  '
  '
  'case 52 '#EMIT 'cef
  '
  'if isb(ascn) then
  '  w1=captureblock(s,i,"")
  '  striplineno(w1)
  '  appendc(w1)
  'else
  '  yesno(s,i,cef)
  'end if
  'goto mainloop
  '
  '
  case 53 'ADDR 'pseudo-instruction
  '
  w2=""
  wr=pword(s,i)
  if mc<>-10 then
    w1=wr
    wr=qeax
  else
    if ascn=44 then i+=1
    w1=pword(s,i)
  end if
  w2=""
  w3=""
  if ascw=91 then
    w3=wpfx
    if len(w3) then
      replace(w3,qedi,wr)
    end if
    if isdstr(typ) then
      w2="mov "+wr+cm+w1+cr
      if typ>=&he0 then
        w2+="mov "+wr+cm+"["+wr+"]"+cr
      end if
    else
      replace(w1,qedi,wr)
      w2="lea "+wr+cm+w1+cr
    end if
  elseif isq(ascw) then
    if wr<>qeax then
      ers="string literals use register "+qeax+" not "+wr: ert=402 : goto exitap
    end if
    w2=stodata(w1)
   elseif (mc>=-5)and(mc<=-4) then 'obtain possible vector
     w4=pword("@"+w1,1)
     if ascw=91 then
       w2="lea "+wr+cm+w4+cr
     else
       w2=linkadd(w1,wr) 'label
     end if
  else 'possible labels
    if isn(ascw) then w1="_"+w1
    w2=linkadd(w1,wr)
  end if
  appendt(w3+w2)
  goto mainloop
  '
  case 54 '#COMPACT
  '
  yesno(s,i,compact)
  if (tranpass<>2)or(dep<>0) then compact=0
  goto mainloop
  '
  case 55 '#CPOINTER
  '
  yesno(s,i,cpoint) : goto mainloop
  '
  case 41 '#CASE
  '
  if nisxn then
    wr=lcase(tword(s,i))
    casf=dic(" insensitive 1, sensitive 2, capital 3, capitalsensitive 3, ",wr)
  end if
  goto mainloop
  '
  case 34 '#FILE
  '
  if nisxn then
    w1=lexiword(s,i)
    w2=lcase(right(w1,3))
    a=dic(" dll 1, exe 2, ",w2)
    if a=0 then
      'if right(w1,2)=".c" then 'cef
      '  cexn=w1
      '  'cef=1
      '  goto mainloop
      'end if
      ert=5 : ers="#file requires name.exe or name.dll " : goto exitap
    end if
    '
    pexn=w1
    pef=a
    '
    do
      if isxn then exit do
      w1=tword(s,i)
      if w1="independent" then independent=1 : continue do
      cpus(w1)
    loop
  end if
  goto mainloop
  '
  case 35 'EMBEDFILE
  '
  w1=""
  if nisxn then
    wd=lexiword(s,i)
    'RESOLVE FILE PATH
    '
    if len(ipath) then
      wd=ipath+wd
    end if
    '
    if pPathCall then
      pch=inclpath(wd)
      a=lenzs(pch)
      wd=ps_to_str(pch,a)
    end if
    if ascn=44 then
      i+=1
      w1=mword(s,i) 'could be a bstring or a sys type of variable
      if asc(w1)<>91 then
        ers="Undefined variable: "+w1 : ert=63 : goto exitap
      end if
      '
      ebdi+=1
      if ebdi>255 then
        ers="Too many embedded files "+wd : ert=61 : goto exitap
      end if
      getfile(wd,ebd(ebdi))
      if len(ebd(ebdi))=0 then
        ers="Problem with file "+wd : ert=62 : goto exitap
      end if
    end if
  end if
  appendt(embeddata()+wpfx+operi(2,cpuw,w1)) 'assign pointer to w1
  goto mainloop
  '
  '
  case 100 to 199 'META COMMANDS: #IFDEF ETC
  '
  metaco(s,i)
  if ert then goto exitap
  goto mainloop
  '
  '
  case 200 to 299 'COMPILE TIME DIAGNOSTICS
  w1="" : w2="" : w3=""
  if isq(ascn) then w3=lexiword(s,i)
  if ise(ascn) then goto mainloop
  w1=tword(s,i) 'no macro expansion
  if tranpass<=2 then
    select case md
    case 201 '#BLOCKDEPTH
      w2=" "+str(brc)
    case 202 '#RECORDOF
      a=lookupm(w1)
      if a then
        w2=writestates(a,a)
        replace(w2,dfd,cr+"--------")
      else
        w2=w1+" Not found"
      end if
    case 203 '#LIST
      a=0 : b=0 : c=0 : d=0 : e=len(w1)
      if dtf then
        w4=left(w1,dtf-1)
        c=lookupm(w4)
        if c then
          d=maco(c,0)
          if d>=htyp then d-=htyp
          if d<=0 then d=c 
          w2=macso(d,1) 'BODY OF TYPE / CLASS / MACRO
          a=me 'NO SCAN
          b=len(w2)
        end if
      end if
      do 'SCAN ALL SYMBOLS
        if c>=64 then exit do
        if a>=me then exit do
        w4=macso(a,0)
        'if w1=left(w4,e) then
        if instr(w4,w1) then
          'itr original symbol case
          'itr secondary keywords / inherits as byref etc.
          w5=ssn(maco(a,6))
          if len(w5)=0 then
            if a<mesb then w5="(core)" else w5="(main source)" 
          end if
          d=maco(a,7)
          if d then w4=macso(d,0)+w4 'PREFIX NAMESPACE
          w4+=" in "+w5
          ape(w2,b,w4+cr) : c+=1 'BUFFER
        end if
        a+=1
      loop
      w2=left(w2,b)
    end select
    if len(w3) then
      open w3 for output as 3 : print #3,w2 : close(3) 'LIST TO FILE
    else
      qq w2,brc 'LIST TO SCREEN
    end if
  end if
  goto mainloop
    '
  end select 'mc=-13
  '
  '
  '======
  addsrc:
  '======
  '
  '
  'ADD ANY UNPROCESSED CODE
  'PASS THRU UNPROCESSED WORDS
  'INCLUDE SINGLE CR/LF (NOT MULTIPLE CR)
  '
  a=asc(s,i)
  select case a
  case 10 : w1=cr  : i+=1
  case 13 : w1=cr  : i+=2
  case 44 : w1="," : i+=1
  case else
    w1=" "
  end select
  wsg=wr
  appendt(wsg+w1) ' given spacing, line breaks etc
  '
  nl=0
  '
  '
  '
  'END-OF-LINE CHECKS
  '==================
  '
  if a<=13 then
    '
    if a=0 then
      '
      'END OF CURRENT SOURCE STREAM
      'CHECK FOR OTHER STREAMS
      'INSERT NEXT INCLUDED CONTENT, IF ANY
      '
      if fq then
        fq-=1 'RESUME PREVIOUS SOURCE CODE
        i=1 : s=sst(fq)
        skiplspace(s,i)
        if fq then wd=ssf(fq-1) else wd="main source"
        appendt("'_"+qu+wd+qu+cr) 'EMBED CURRENT FILENAME FOR ASSEMBLERS
        cfile=wd
        goto mainloop
      end if
      '
      'default termination coding
      '
      if tranpass>1 then
        '
        if nsi then appendt("namespace"+cr) 'RESUME GLOBAL NAMESPACE
        '
        if (tmnt=0)and(dep=0) then
          if pef=1 then
            wva(3)+=cr+"sub finish() external"+cr+"terminate"+cr+"end sub"+cr+_
                        "mov "+qeax+cm+"1"+cr 'FINISH WHEN DLL IS UNLOADED
          else
            wva(3)+=cr+"._end_"+cr+"terminate"+cr 'FOR NON-PERSISTENT PROGS
          end if
          tmnt=1
        end if
        '
        if nsi then
          appendt("namespace"+cr)
          nsi=0
        end if
        '
        'CHECK FOR REMAINING CODE
        '
        if epi=0 then
          a=lookupm("_epilog")
          if a then wva(3)+=cr+macso(a,1)
          epi=1
        end if
        '
      end if 'tranpass>1
      '
      s=wva(3)
      nsi=0
      '
      if len(s) then
        wva(3)=""
        i=1
        goto mainloop
      end if
      '
      '
      'EXHAUSTED ALL INPUT STREAMS
      '
      exit do ' no proc mapping
      '
    end if
    '
    goto mainloop
    '
  end if
  '
  '
  '==========================
  loop 'FOR ANOTHER STATEMENT
  '==========================
  '
  '
  exitap: 'COMPILE TERMINATION AND ERROR HANDLING
  '======
  '
  '
  'REPORT ERRORS
  '=============
  '
  if ert=0 then
    if nsl then
      ow="" : lbw=""
      nsl-=1
      select case ctb(nsl)
      case 1 : w1="if..end if"
      case 2 : w1="do .. end do"
      case 3 : w1="while .. end while"
      case 4 : w1="for .. next"
      case 5 : w1="Select .. end select"
      end select
      ers="Unterminated blocks at end of script "+w1+cr+cln(nsl)
      ert=30
    elseif funi then
      ow="" : lbw=""
      ers="unterminated procedure "+funm : ert=30
    elseif brc then
      ow="" : lbw=""
      ers="unclosed brackets at end of script ("+str(brc)+")" : ert=29
    end if
  end if
  '
  if ert>0 then
    '
    w1="ERROR:"
    select case ert
    case 1   : w1="ALERT: "
    case 101 : ers+="Macro undefined or out of scope"
    case 102 : ers+="Macro recursion suspected: "
    case 103 : ers+="Method/property element not implemented"
    case 104 : ers+="Method pointer must have a size of "+str(cpuw)+" bytes"
    end select
    '
    endline(s,i) :    ers =w1+htb+ers+cr
    '
    if len(ow)    then ers+="WORD: "+htb+ow+cr
    if funi then ers+="IN: "+htb+wn+cr
    'if len(lbw)  then ers+="BELOW:"+htb+lbw+cr
    ers+="LINE: "+htb+lnmks+cr
    if len(cfile) then ers+="FILE: "+htb+cfile+cr
    'ers+="PASS: "+htb+str(tranpass)+cr
    '
    if vew>=2 then appendt(ers)
    '
  end if
  '
  '
  'REVERT TO DEFAULT PUNCTUATION
  '
  ct2=59
  sr2=58
  '
  t=left(t,j-1)
  '
  donetran:
  '========
  '
  if compact=0 then
    'final high pass only
    'open "t.txt" for output as 3 : print #3,t : close(3) 'examine generic
    'open "s.txt" for output as 3 : print #3,left(proclist,plistend-1) : close(3) 'examine generic
  end if
  '
  ' "words processed ",mct
  '
end sub

