flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > [fasmg] macro doesn't redefine after wrapping it in another

Author
Thread Post new topic Reply to topic
SArpnt



Joined: 29 Sep 2026
Posts: 6
SArpnt 08 Oct 2026, 07:41
Code:
; normally i would use a local for endpos but this makes the issue clearer
macro block! name*
        macro end.block!
                name._endpos:
                purge end.block
        end macro
        label name: name._endpos - name
end macro
; should have the exact same behavior as `block`
macro wrapped name*
        macro end.wrapped!
                end block
                purge end.wrapped
        end macro
        block name
end macro

; this works fine. block a starts, block b starts, block b ends, block a ends.
block a
        block b
        end block
end block

; this fails, it looks like the second definition of `end.block` never gets created?
wrapped x
        wrapped y
        end wrapped
end wrapped
    


Code:
flat assembler  version g.l8vn
test.asm [27]:
        wrapped y
macro wrapped [11]:
        label name: name._endpos - name
Processed: label y: y._endpos - y
Error: symbol 'y._endpos' is undefined or out of scope.
test.asm [29]:
        end wrapped
macro end?.wrapped [1] macro end?.block [1]:
        x._endpos:
Processed: x._endpos:
Error: definition of 'x._endpos' in conflict with already defined symbol.
    

i can't think of any reason why `wrapped` would have different behavior other than it being a bug. `wrapped y` should create an `end block` that creates `y._endpos`, but it creates `x._endpos` twice, which shouldn't be possible. even if `wrapped y` didn't create an `end block`, it should fail on the second `end wrapped`, because `end block` purges itself.[/code]
Post 08 Oct 2026, 07:41
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8564
Location: Kraków, Poland
Tomasz Grysztar 08 Oct 2026, 09:53
An unconditional macro becomes unrolled even during a definition of another macro.

For example, this means that your "wrapped" macro is actually defined as such:
Code:
macro wrapped name*
        macro end.wrapped!
                end block
                purge end.wrapped
        end macro
        ; unrolled unconditional "block" macro;
        macro end.block!
                name._endpos:
                purge end.block
        end macro
        label name: name._endpos - name
end macro    
The argument "name" becomes replaced with value "name" from "block name" and everything happens to work out here.

However, there is another effect when the "wrapped" macro is called one after another (nested as in your example), because until the outer block is closed, "end.block" is defined as unconditional macro. It becomes unrolled in the definition of the "end.wrapped" macro, and so "end.wrapped" has the previous definition of "end.block" unrolled in its body.

You can verify that the problem disappears if you don't make "end.block" unconditional:
Code:
macro block! name*
        macro end.block
                name._endpos:
                purge end.block
        end macro
        label name: name._endpos - name
end macro

macro wrapped name*
        macro end.wrapped!
                end block
                purge end.wrapped
        end macro
        block name
end macro

block a
        block b
        end block
end block

wrapped x
        wrapped y
        end wrapped
end wrapped    
If you need it unconditional, though, you can work around it by adding an ESC to prevent the unconditional macro from being unrolled while macro is being defined:
Code:
macro block! name*
        macro end.block!
                name._endpos:
                purge end.block
        end macro
        label name: name._endpos - name
end macro

macro wrapped name*
        macro end.wrapped!
                esc end block
                purge end.wrapped
        end macro
        block name
end macro

block a
        block b
        end block
end block

wrapped x
        wrapped y
        end wrapped
end wrapped    
Post 08 Oct 2026, 09:53
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.