include 'CDStack.INC'
cnt = 0
macro calc dst, exp{
 if 1>2 ;exp eqtype 0
  mov dst, dword exp
 else
  local push_p, c1, c2
  macro push_p x& \{
    local t
    virtual at -8
      x
      db 8 dup 0
      load t qword from -8
      t = t or (1 shl ($*8))
      push_c c1, t and $ffffffff
      push_c c2, t shr 32
    end virtual
  \}
  local r, s, L, T, t1, t2, t0, lst, matched, endl
  stackinit r, 1000  ;rank
  push_c r, -3
  push_c r, -1
  stackinit s, 1000  ;symbols
  push_c s, 0
  push_c s, 0
  stackinit c1, 1000
  stackinit c2, 1000
  L = 0
  T equ 0
  lst equ []
  irps x , exp endl\{
    match =0, T \\{
      matched = 0
      match =+, x \\\{
        matched = 1          ; t1=odd  ->
        t1 = 1+L             ; t1=even <-
        match =[], lst \\\\{ matched = 11
                            t1 = 6\\\\}
        match =(, lst \\\\{ matched = 11
                            t1 = 6\\\\}
      \\\}
      match =-, x \\\{
        t1 = 1+L
        matched = 2
        match =[], lst \\\\{ matched = 12
                            t1 = 6\\\\}
        match =(, lst \\\\{ matched = 12
                            t1 = 6\\\\}
      \\\}
      match =*, x \\\{
        matched = 3
        t1 = 3+L
      \\\}
      match =/, x \\\{
        matched = 4
        t1 = 3+L
      \\\}
      match =%, x \\\{
        matched = 5
        t1 = 3+L
      \\\}
      if endl eq x
        matched = 19
        t1 = -2
      end if
      match =(, x \\\{
        matched = -1
        L = L + 100
      \\\}
      match =), x \\\{
        matched = -1
        L = L - 100
      \\\}
      match =[, x \\\{
        matched = -1
        T equ 1
        t0 equ
      \\\}
      if matched < 0
      else if matched > 0
        while 1<2
          top_cs r, t2
          if t2<t1 | (t2=t1 & t1 mod 2 = 0)
            break
          end if
          if cnt>100
            break
          end if
          cnt = cnt+1
          pop_cs r
          pop_cs s, t2
          if t2 = 1
            push_p rept 1\\\{pop eax\\\} add [esp], eax
          else if t2 = 2
            push_p rept 1\\\{pop eax\\\} sub [esp], eax
          else if t2 = 3
            push_p rept 1\\\{pop eax\\\} rept 1\\\{mul dword [esp]\\\} mov [esp], eax
          else if t2 = 4
            push_p rept 1\\\{pop ecx eax\\\} rept 1\\\{xor edx, edx\\\} rept 1\\\{div ecx\\\} push eax
          else if t2 = 5
            push_p rept 1\\\{pop ecx eax\\\} rept 1\\\{xor edx, edx\\\} rept 1\\\{div ecx\\\} push edx
          else if t2 = 11
            ;nop
          else if t2 = 12
            push_p neg dword [esp]
          end if
        end while
        push_c r, t1
        push_c s, matched
      else if x eqtype 0 | x eqtype eax
        push_p push x
      end if
    \\}
    match =1, T \\{
      t0 equ t0 x
      match ], x \\\{
        push_p push dword t0
        T equ 0
      \\\}
    \\}
    lst equ x
  \}
  load matched dword from c1:-4
  repeat matched
    load t1 dword from c1:%*4-4
    load t2 dword from c2:%*4-4
    t1 = t1 + (t2 shl 32)
    while t1>1
      db t1 and 255
      t1 = t1 shr 8
    end while
  end repeat
  pop dword dst
 end if
}    push_c pushs a value to the stack, pop_c pops one, top_c get the top, pop_cs pop one with sign