;===============================================================================
;
; MacroArgBegin
;
; Begin the parsing of a macro argument, by adding the file of the argument
; in the files list
;
; in a2 Point to "\xxx"
; a5 FILE*
;
; out updated. Org a2 will point after the arg replaced
; updated a5
;
; destroy sp is modified
;
;===============================================================================
MacroArgBegin:
move.w MACRO_REF_COUNT(fp),d2 ; Counter (dbf) to find the FILE which contains the arg
addq.w #1,MACRO_ARG_REF_COUNT(fp) ; Update arg counter
cmp.w MACRO_ARG_REF_COUNT(fp),d2
bhi ErrorInvalidOutOfMacro ; We are sure to avoid an underflow when browsing the files list
;----------------------------------------------------------------------
; Get the rank of the arg to replace
;----------------------------------------------------------------------
addq.l #1,a2 ; Skip \
movea.l a2,a0
bsr ReadIntBase10 ; #arg in d0
tst.b d1
bne ErrorInvalidMacroArg
move.l d0,d1 ; Save arg rank
movea.l a0,a2 ; Move the cursor after the macro arg
bsr SaveCursor ; Save current FILE state
;----------------------------------------------------------------------
; Get the file which contains the macro arguments
; This is the file which is before the Macro file
; It can be any previous file of the list
;----------------------------------------------------------------------
movea.l a5,a0
\Loop: cmpi.w #FILE.Type.Macro,FILE.Type(a0)
beq.s \Macro
addq.w #1,d2
\Macro: movea.l FILE.Parent(a0),a0
dbf.w d2,\Loop
;----------------------------------------------------------------------
; Add the file to the list and initialize it
;----------------------------------------------------------------------
movea.l (sp)+,a1 ; Save return value
lea -FILE.sizeof(sp),sp ; Create FILE
pea (a1) ; Restore return value
move.l sp,FILE.Child(a5) ; Save child in parent
move.l a5,FILE.Parent(sp) ; Save parent in child
movea.l sp,a5
move.w FILE.Handle(a0),FILE.Handle(a5) ; Create a copy of the file which contains the macro args
move.w FILE.CursorOffset(a0),FILE.CursorOffset(a5)
move.w FILE.NumLine(a0),FILE.NumLine(a5)
move.w #FILE.Type.MacroArg,FILE.Type(a5)
clr.l FILE.Child(a5)
;----------------------------------------------------------------------
; Check if the parameter list begins with .b/.s/.w/.l (so first arg is #0, not #1)
;----------------------------------------------------------------------
\Check: bsr RestoreCursor ; Get a pointer to the beginning of the first arg in a2
move.b (a2),d0
beq.s \Not0
IF_D0 's',\CheckNextChar
IF_D0 'b',\CheckNextChar
IF_D0 'w',\CheckNextChar
IF_D0 'l',\CheckNextChar
\Not0: subq.w #1,d1 ; Arg counter
bmi ErrorInvalidMacroArg ; Arg was \0, but no valid size found
\Arg0:
;----------------------------------------------------------------------
; Find the right argument
; To get the next argument, we skip chars until a comma, but some chars are forbidden
;----------------------------------------------------------------------
\SkipLoop:
subq.w #1,d1
bmi.s \End
\Next: move.b (a2)+,d0
beq ErrorInvalidMacroArg
IF_D0 ',',\SkipLoop
IF_D0 EOL,ErrorInvalidMacroArg
IF_D0 HTAB,ErrorInvalidMacroArg
IF_D0 SPACE,ErrorInvalidMacroArg
IF_D0 ASM_COMMENT_CHAR,ErrorInvalidMacroArg
bra.s \Next
\End: rts
\CheckNextChar: ; Check that the char which follows a size is valid
move.b 1(a0),d0
beq.s \Arg0
IF_D0 ',',\Arg0
IF_D0 EOL,\Arg0
IF_D0 HTAB,\Arg0
IF_D0 SPACE,\Arg0
IF_D0 ASM_COMMENT_CHAR,\Arg0
bra.s \Not0