format PE console
entry Start

include '%fasminc%\macro\proc32.inc'
include '%fasminc%\macro\import32.inc'
include '%fasminc%\macro\struct.inc'

struc TCHAR [val] { common match any, val \{ . db val \}
                           match , val \{ . db ? \} }

macro allow_nesting
{ macro pushd value
  \{ match ,value \\{
      pushx equ \\}
     match =pushx =invoke proc,pushx value \\{
      allow_nesting
      invoke proc
      purge pushd,invoke,stdcall,cinvoke,ccall
      push eax
      pushx equ \\}
     match =pushx =stdcall proc,pushx value \\{
      allow_nesting
      stdcall proc
      purge pushd,invoke,stdcall,cinvoke,ccall
      push eax
      pushx equ \\}
     match =pushx =cinvoke proc,pushx value \\{
      allow_nesting
      cinvoke proc
      purge pushd,invoke,stdcall,cinvoke,ccall
      push eax
      pushx equ \\}
     match =pushx =ccall proc,pushx value \\{
      allow_nesting
      ccall proc
      purge pushd,invoke,stdcall,cinvoke,ccall
      push eax
      pushx equ \\}
     match =pushx,pushx \\{
      pushd <value>
      pushx equ \\}
     restore pushx \}
  macro invoke proc,[arg]
  \{ \reverse pushd <arg>
     \common call [proc] \}
  macro stdcall proc,[arg]
  \{ \reverse pushd <arg>
     \common call proc \}
  macro cinvoke proc,[arg]
  \{ \common size@ccall = 0
	     if ~ arg eq
     \reverse pushd <arg>
	      size@ccall = size@ccall+4
     \common end if
	     call [proc]
	     if size@ccall
	     add esp,size@ccall
	     end if \}
  macro ccall proc,[arg]
  \{ \common size@ccall = 0
	     if ~ arg eq
     \reverse pushd <arg>
	      size@ccall = size@ccall+4
     \common end if
	     call proc
	     if size@ccall
	     add esp,size@ccall
	     end if \} }

macro pushd value
{ match first=,more, value \{ \local ..continue
   call ..continue
   db value,0
   ..continue:
   pushd equ \}
  match pushd =addr var,pushd value \{ \local ..opcode,..address
   virtual at 0
    label ..address at var
    mov eax,dword [..address]
    load ..opcode from 0
   end virtual
   if ..opcode = 0A1h
    push var
   else
    lea edx,[..address]
    push edx
   end if
   pushd equ \}
  match pushd =double [var],pushd value \{
   push dword [var+4]
   push dword [var]
   pushd equ \}
  match pushd =double =ptr var,pushd value \{
   push dword [var+4]
   push dword [var]
   pushd equ \}
  match pushd =double num,pushd value \{ \local ..high,..low
   virtual at 0
    dq num
    load ..low dword from 0
    load ..high dword from 4
   end virtual
   push ..high
   push ..low
   pushd equ \}
  match pushd,pushd \{ \local ..continue
   if value eqtype ''
    call ..continue
    db value,0
    ..continue:
   else
    pushd value
   end if
   pushd equ \}
  restore pushd }

allow_nesting

include '%fasminc%\equates/kernel32.inc'
include '%fasminc%\equates/user32.inc'
include '%fasminc%\equates/shell32.inc'
include 'idata.inc'

