flat assembler
Message board for the users of flat assembler.

Index > Programming Language Design > Grouping source sections with fasmg

Author
Thread Post new topic Reply to topic
bitRAKE



Joined: 21 Jul 2003
Posts: 3387
Location: vpcmipstrm
bitRAKE
Another idea: POSTPONE should allow named groups - which can be selectively evaluated.
Code:
postpone strings
        MyMessage.caption db "Caption",0
        MyMessage.message db "Message",0
end postpone

MyMessage:
        invoke MessageBox,0,\
                ADDR .message,\
                ADDR .caption,\
                MB_OK or MB_ICONSTOP
        retn
.data
        posit wstrings,strings ; if a name is unused it is ignored    
POSIT is proposed as the operator to evaluate named POSTPONE groups some alternatives:
    propound - uncommon
    present - too many meanings


I've explored several other methods to realize this grouping. Yet, named POSTPONE groups just seems more intuitive to me: get nails at the hardware store, John should know about this, Amy speaks French. Labeled grouping of information in this way is something we do on a daily basis.

For example, macro stack is one alternative:
Code:
macro strings
end macro
macro strings
        MyMessage.caption db "Caption",0
        MyMessage.message db "Message",0
        strings
end macro    
Another method is symbol value stacking.

There are just a lot of uses which benefit - similar to how VIRTUAL functionality is so powerful - POSTPONE could also have greater utility. There are decisions to make about multiple evaluations of the same group. Should the group naming exist in a different symbolic space - just for code fragments?

Time to look into implementing ...
Post 10 Feb 2022, 17:14
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7990
Location: Kraków, Poland
Tomasz Grysztar
Isn't it just another variation on the "globals" concept, like the IncludeIGlobals/IncludeUGlobals from Fresh project? And these macros were for fasm 1 already. Although with fasmg it is possible to make it more capable, with forward referencing possibility.

I have also mentioned the macro stacking solution in the "How can multiple sections of file be generated in parallel?" section of supplementary documentation, but I have not given any examples there, perhaps I should. But this is something that is likely even better done with CALM.
Post 10 Feb 2022, 17:43
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3387
Location: vpcmipstrm
bitRAKE
Ah, do you mean this example:
Code:
                include '8086.inc'
                org     100h
                jmp     CodeSection

        DataSection:

                virtual
                        Data::
                end virtual

                postpone
                        virtual Data
                                load Data.OctetString : $ - $$ from $$
                        end virtual
                end postpone

                db Data.OctetString

        CodeSection:

                virtual Data
                        Hello db "Hello!",24h
                end virtual

                mov     ah,9
                mov     dx,Hello
                int     21h

                virtual Data
                        ExitCode db 37h
                end virtual

                mov     ah,4Ch
                mov     al,[ExitCode]
                int     21h    
... postpone groups do not seem to add any additional functionality at the data level. I'll need to think about if forward referencing solves all the deferred evaluation problems for things like relocation and exception data as well. Presently cannot think of a scenario that would be problematic.

Making things more difficult than they need to be perhaps.

_________________
¯\(°_o)/¯ unlicense.org
Post 10 Feb 2022, 19:00
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7990
Location: Kraków, Poland
Tomasz Grysztar
bitRAKE wrote:
Ah, do you mean this example
I meant the missing example, alternative solution through stacked macros or a list of macros, which is only mentioned as a possibility in the later paragraph.

With CALM, it could be something like:
Code:
define collections

macro? collect? name*
        calminstruction name
                local   tmp
            reverse:
                take    tmp, collections.name
                jyes    reverse
            execute:
                take    collections.name, tmp
                jno     done
                assemble collections.name
                jump    execute
            done:
        end calminstruction
        calminstruction ?! line&
                match   =end? =collect?, line
                jyes    close
                take    collections.name, line
                exit
            close:
                arrange line, =purge ?
                assemble line
        end calminstruction
end macro    
Code:
collect strings
        caption db "Caption",0
end collect

collect strings
        message db "Message",0
end collect

strings    


And here's a variant that allows to put "strings" block before the collected parts are defined:
Code:
define collections

macro? collect? name*
        if ~ defined collections..name
                restore collections..name
                define collections..name
                calminstruction collections..name
                        local   tmp
                    reverse:
                        take    tmp, collections.name
                        jyes    reverse
                    execute:
                        take    collections.name, tmp
                        jno     done
                        assemble collections.name
                        jump    execute
                    done:
                end calminstruction
                define collections.name macro name:
                postpone
                        define collections.name end macro
                        collections..name
                end postpone
        end if
        calminstruction ?! line&
                match   =end? =collect?, line
                jyes    close
                take    collections.name, line
                exit
            close:
                arrange line, =purge ?
                assemble line
        end calminstruction
end macro    
And, of course, the macro stacking method that you mentioned:
Code:
define collections

macro collect?! name*
        local new
        if defined collections.name
                macro name
                        name
                        new
                end macro
        else
                collections.name = 0
                macro name
                        new
                end macro
        end if
        collections.name = collections.name + 1
        esc macro new
end macro

macro end?.collect?!
        esc end macro
end macro    
This may be the one to include as an example in the docs, as it is the simplest one and does not need CALM. And this one also can be made "asynchronous", allowing to put the result before the definitions:
Code:
define collections

macro collect?! name*
        local new, previous
        match :s:, collections.name
                macro previous!
                        s
                end macro
        else
                macro previous!
                end macro
                postpone
                        match :s:, collections.name
                                macro name
                                        s
                                end macro
                        end match
                end postpone
        end match
        restore collections.name
        define collections.name :new:
        esc macro new
                previous
end macro

macro end?.collect?!
        esc end macro
end macro    
Post 10 Feb 2022, 20:10
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3387
Location: vpcmipstrm
bitRAKE
These techniques work beautifully in:
Code:
macro lea? line&
        match any=,=<values=>,line
                local name
                collect _CONST_
                        label name
                        values
                end collect
                lea any,[name]
        else
                lea line
        end match
end macro
macro _T line&
        TCHAR line,0
end macro    
I can use syntax like:
Code:
lea rax,<_T "bitRAKE">    
... but I get some strange errors without the space between _T and the quote/apostrophe character. Not a show stopper - just curious why fasmg would come back with:
Code:
ex1.asm [60]:
        lea rax,<_T'bitRAKE'>
macro lea? [9]:
        lea line
Processed: lea rax,<_T'bitRAKE'>
Error: missing closing chevron.    
... clearly the chevon is there. It's like the quote is not separated from the _T and the quotation begins later?

_________________
¯\(°_o)/¯ unlicense.org
Post 25 Mar 2022, 21:40
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7990
Location: Kraków, Poland
Tomasz Grysztar
bitRAKE wrote:
I can use syntax like:
Code:
lea rax,<_T "bitRAKE">    
...
This is quite similar to what my GLOBSTR package intended to do, you could also combine it with inline macros. I've been just recently thinking that I should include something like that as an example in the repository:
Code:
include 'win64ax.inc'
include 'globstr_reuse.inc' ; the second version from the "Global strings" thread
include 'inline.inc'

macro fastcall?.inline_string var
        local data
        match value, var
                data GLOBSTR value,0
        end match
        redefine var data
end macro

inlinemacro GLOB(value)
        local data
        data GLOBSTR value,0
        return equ data
end inlinemacro

.code

  start:

        invoke  MessageBox,HWND_DESKTOP,'First!',"Demo",MB_OK

        lea     rdx,[GLOB("Second!")]
        invoke  MessageBox,HWND_DESKTOP,rdx,"Demo",MB_OK

        invoke  ExitProcess,0

.data

  GLOBSTR.here

.end start    


bitRAKE wrote:
but I get some strange errors without the space between _T and the quote/apostrophe character. Not a show stopper - just curious why fasmg would come back with:
Code:
ex1.asm [60]:
        lea rax,<_T'bitRAKE'>
macro lea? [9]:
        lea line
Processed: lea rax,<_T'bitRAKE'>
Error: missing closing chevron.    
... clearly the chevon is there. It's like the quote is not separated from the _T and the quotation begins later?
There should be no error there, since either _T'bitRAKE' or _T"bitRAKE" are valid names (for all fasm versions). You probably found some kind of a bug, but I'm not able to reproduce it, I may be missing some context that makes it show up.
Post 26 Mar 2022, 11:13
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3387
Location: vpcmipstrm
bitRAKE
It's not an error in fasmg. I forgot that _T"test": is a valid label name. So, I need the space to split them. I was happy when it didn't prune the <> and I was able to detect that syntax.

_________________
¯\(°_o)/¯ unlicense.org
Post 27 Mar 2022, 08:09
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3387
Location: vpcmipstrm
bitRAKE
Originally, I tried:
Code:
struc TD_BUTTONS line&
        local name
        collect _CONST_
        iterate <quoted,id>,line
                align sizeof.TCHAR
                label name.%
                TCHAR quoted,0
                if % = %%
                        . equ name
                        align 4
                        label name:%%
                        repeat %%
                                indx %
                                dd id
                                dq name.%
                        end repeat
                end if
        end iterate
        end collect
end struc    
... fasmg errors:
Code:
_CONST_ [10] macro TCHAR [1] du? [14] macro WCHAR [2]:
        if arg eqtype ''
Processed: if quoted eqtype ''
Error: symbol 'quoted' is undefined or out of scope.    
.. I was able to create a working version using collect. It's like the ITERATE doesn't have all the code to update symbols. And seems, as long as each line can operate in isolation collect works.
Post 29 Mar 2022, 10:37
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7990
Location: Kraków, Poland
Tomasz Grysztar
bitRAKE wrote:
It's like the ITERATE doesn't have all the code to update symbols.
The ASSEMBLE command does not do parameter preprocesing (because CALM is kind of a replacement for the standard preprocessor), that's what causes the problem here. A workaround could be to put all these lines into a single-use macro and then call that macro to provide standard preprocessing that is missing.

Another workaround: use conditional interceptor instead of unconditional one ("?" instead of "?!"). This way things like IF or ITERATE would be evaluated before collecting. This would require modifications of how "end collect" is detected:
Code:
define collections

macro collect? name*
        calminstruction name
                local   tmp
            reverse:
                take    tmp, collections.name
                jyes    reverse
            execute:
                take    collections.name, tmp
                jno     done
                assemble collections.name
                jump    execute
            done:
        end calminstruction
        calminstruction ? line&
                match   /=collect?, line
                jyes    close
                take    collections.name, line
                exit
            close:
                arrange line, =purge ?
                assemble line
        end calminstruction
end macro

macro end?.collect?!
        /collect
end macro    
Post 29 Mar 2022, 11:28
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3387
Location: vpcmipstrm
bitRAKE
The single use macro seems very flexible:
Code:
struc TD_BUTTONS line&
        local name
        struc name.struc
        iterate <quoted,id>,line
                align sizeof.TCHAR
                label name.%
                TCHAR quoted,0
                if % = %%
                        . equ name
                        align 4
                        label name:%%
                        repeat %%
                                indx %
                                dd id
                                dq name.%
                        end repeat
                end if
        end iterate
        end struc
        collect _CONST_
                . name.struc
        end collect
end struc    
I did try the conditional collector, but fasmg's reply was:
Code:
_CONST_ [10]
Processed: indx 1
Error: unexpected instruction.    
I'm still going to use it with the single use macro as that is probably closer to what I am expecting, for now.

_________________
¯\(°_o)/¯ unlicense.org
Post 29 Mar 2022, 15:32
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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.