; ( These macros make development easier. They provide a
;   layer of abstraction between Forth and the CPU. )

;---------------------------------------------------------------------
; Multiple push/pop
;	push eax,ebx,ecx...
;	pop eax,ebx,ecx...

%macro push 1-*.nolist
%rep %0
	push dword %1
%rotate 1
%endrep
%endmacro

%macro pop 1-*.nolist
%rep %0
%rotate -1
	pop dword %1
%endrep
%endmacro
%macro dup 0
        sub esi,byte 4
        mov [esi],eax
%endmacro
%macro drop 0
        lodsd
%endmacro
%macro variable 2
       call dovar
       %1 dd %2
%endmacro
%macro swap 0
       xchg eax,[esi]
%endmacro
%macro nip 0
       add esi,byte 4
%endmacro

%macro embed 1
   upsh %%e1
   upsh [%%e2]
   call eval	
   jmp short %%e3
%%e1 db %1
%%e2 dd $-%%e1
%%e3
%endmacro


%macro next 0
       ret
%endmacro

%macro upsh 1
        dup
        mov eax,%1
%endmacro
%macro upop 1
        mov %1,eax
        drop
%endmacro
;-------------------------------------------------------------------------
; Dictionary Macros (based on IsForth's)

; Usage: code 'forth-name', asm-name
%macro code 2.nolist
%2:                         ;make label for new coded definition
%endmacro
%macro mcode 2.nolist
%2:                         ;make label for new coded definition
%endmacro


; Usage: var 'name',name,value
%macro var 3.nolist
 code %1, ?%2
 call dovar
 %2 dd %3
%endmacro

; Usage: const 'name',name,value
%macro const 3.nolist
 code %1, ?%2
 call doconstant
 %2 dd %3
%endmacro

;=========================================================================
%macro case 2
cmp eax, %1
jz .%2
%endmacro

; Usage: autoexec <label>
;  Calls the label at startup
%macro autoexec 1
	%ifndef autoexec_list
	  %xdefine autoexec_list %1
	%else
	  %xdefine autoexec_list autoexec_list,%1
	%endif
%endmacro

%macro inline 1-*.nolist
%rep %0
	upsh %1
	call comma1
%rotate 1
%endrep
%endmacro

%macro e 2	; 'name', label
%%last
  dd %2		; CFA
  db %%lfa-$-1	; Length of name
  db %1		; 'name'
%%lfa
  dd %%last-4	; next LFA
%endmacro

%macro set 2
  %1 equ %2
%endmacro
