flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Parsing complex DUP with fasmg

Author
Thread Post new topic Reply to topic
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8353
Location: Kraków, Poland
Tomasz Grysztar 07 Apr 2019, 16:57
With fasmg it is generally very easy to override standard data directives, to extend their syntax options or do things like relocation processing:
Code:
macro dd data&
        iterate unit, data
                match ?, unit
                        dd ?
                else match count =dup? value, unit
                        dd unit
                else
                        if unit relativeto 0
                                dd unit
                        else
                                ; process relocation
                        end if
                end match
        end iterate
end macro    
What this simple ITERATE approach does not handle well, is the DUP operator with multiple data items. The commas inside DUP statement break the expression into separately iterated parts, because ITERATE expects <...> encapsulation for comma-containing portions, not (...) that legacy DUP syntax has.

Admittedly, fasm in general does not handle complex DUP statements well - because of its principle design of each line being a simple statement (the same quirk that makes inline macros not possible in fasm's architecture). The nested DUP expressions, allowed in classic assemblers like TASM, do not work neither in fasm 1 nor in fasmg.

But, as usual, flexibility of fasmg's macro language allows to handle it when there is a necessity. As a basis I'm using this package of bracket-balancing macros:
Code:
struc rnbalance: expr&
        match head(tail, :expr:
                . = . + 1
                . rnbalance head
                . rnbalance tail
        else match head)tail, :expr:
                . = . - 1
                . rnbalance head
                . rnbalance tail
        end match
end struc

struc rnbalancesplit expr&
        local a,s
        a = 0
        s = 0
        define .
        iterate el, expr
                a rnbalance el
                if a = 0 & s = 1
                        s = 0
                        match v, .
                                redefine . v,el>
                        end match
                else if a = 0 | s = 1
                        match v, .
                                redefine . v,el
                        else
                                redefine . el
                        end match
                else
                        s = 1
                        match v, .
                                redefine . v,<el
                        else
                                redefine . <el
                        end match
                end if
        end iterate
end struc    
The "rnbalancesplit" macro works on a list of comma-separated arguments and adds <...> enclosing where needed to ensure that parentheses balance out within each of them. The processed list is stored in a symbolic variable. For example:
Code:
example rnbalancesplit 1,2 dup (3,4),5

match value, example
        display `value  ; displays: 1,<2 dup (3,4)>,5
end match    
This makes it easy to create a generalized macro implementing DUP (including nesting) for any data directive:
Code:
macro withdup: instr, data&
        local tmp
        tmp rnbalancesplit data
        match list, tmp
                iterate el, list
                        match count =dup? (values), el
                                repeat count
                                        withdup instr,values
                                end repeat
                        else
                                instr el
                        end match
                end iterate
        end match
end macro    
Use it like:
Code:
withdup DB, 1,2 dup (3,4),5    
It can be used with in conjunction with any instruction, even a custom macro, like this one for testing:
Code:
macro DSHOW? value
        display `value
end macro

withdup DSHOW, 1,2 dup (3,4 dup (+,-)),5  ; displays: 13+-+-+-+-3+-+-+-+-5    
Post 07 Apr 2019, 16:57
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8353
Location: Kraków, Poland
Tomasz Grysztar 08 Apr 2019, 09:41
And now a faster implementation that uses a less general approach and only starts counting brackets when it actually sees the DUP:
Code:
macro withdup: instr, data&
        local a,c,tmp
        a = 0
        iterate el, data
                if a <> 0
                        match prev, tmp
                                redefine tmp prev,el
                        end match
                        a rnbalance el
                else match count =dup? val, el
                        c = count
                        redefine tmp val
                        a rnbalance val
                else
                        c = 0
                        instr el
                end match
                if c > 0 & (a = 0 | % = %%)
                        match (val), tmp
                                repeat c
                                        withdup instr, val
                                end repeat
                        else match val, tmp
                                repeat c
                                        withdup instr, val
                                end repeat
                        end match
                end if
        end iterate
end macro    
It uses only "rnbalance" macro from the previous post.
Post 08 Apr 2019, 09:41
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 08 Apr 2019, 14:20
Fasm in no more needed to be compatibable with others dead assemblers (that were mainstream teen yars ago) - now fasm is mainstream - and increasing clearity of syntax (removing alien elements) is good.
(...) encapsulation looks alien to fasm1 syntax, while <...> is native. May be replace this?
Why fasmg should suffer with dead assemblers compatibility too?
Post 08 Apr 2019, 14:20
View user's profile Send private message Send e-mail 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.