flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > [solved] fasm1: is it posible to isolate locals creation

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
Code:
macro define@struct name,[field,type,def] {
 common
        local list
        list equ
 forward
        local value
        match any, list \{ list equ list, \}
        list equ list <value>
 common
        restruc name
        match values, list \{
                struc name value \\{
                        \\local \\..base
                        match , @struct \\\{ define field@struct .,name,<values> \\\}
                        match no, @struct \\\{
                                label \\..base
                                label . at \\..base \\\}
                \\}
                macro name value \\{
                        match , @struct \\\{
                                \\\local anonymous
                                define field@struct anonymous,name,<values> \\\}
                        match no, @struct \\\{  \\\} \\} \} }    


Tomasz, is any way to produce values list only for named fields?
Let suppose field contain 2 words & we can determine with match if current field is anonymous or not.
It is possible to isolate creation of local for them so way that struc & macro will gain count of parameters only for named fields?

something like:
Code:
forward
        match "unnamed" anon,field \{
                local value
                match any, list \\{ list equ list, \\}
                list equ list <value:def> \}
common
        match values, list \{
                struc name value \\{
forward
                        match "unnamed" anon,field \\\{ type def \\\} 
                        mismatch "unnamed" anon,field \\\{ field type value \\\}
...    


may be some other aproach?

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.


Last edited by ProMiNick on 23 Feb 2019, 21:35; edited 1 time in total
Post 21 Feb 2019, 14:59
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
I'm not sure if I understand the problem, could you try to reduce it to a small example?
Post 21 Feb 2019, 15:43
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
I expect to code so
Code:
struct A
        a dd ?
          dd ?
        b dq ?
ends    


but not so
Code:
struct A
        a dd ?,?
        b dq ?
ends    


so I want that
Code:
struct A
        a dd ?
          dd ?
        b dq ?
ends    

will produce
Code:
struc value?0,value?1 {
       a dd value?0
        dd ?
       b dq value?1 }    

but not
Code:
struc value?0,value?1,value?2 {
       a dd value?0
        dd value?1
       b dq value?2 }    


by 1 value for each named struct member but not for unnamed ones.

Why not
Code:
struct A
        a dd ?,?
        b dq ?
ends    

because 2n field planned to be created by macro align, or other complex macro
Code:
         dd ?    
Post 21 Feb 2019, 16:59
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
I understand what you want to implement, my question was what is the actual problem you have in the implementation you chose. Could you reduce it to a specific question about how the symbolic variables etc. interact? The "struct" macro is quite complex and there are probably many different ways in how you could approach modifying it.
Post 21 Feb 2019, 17:01
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
the simpler is add 4th parametr infront of triplet [extend,field,type,def] and operate according it value.

I already tryed to reduce it as I can. from struct macro set to 1 single macro:
Code:
macro define@struct name,[extend,field,type,def]     

how construct proper struc & macro according to value in symbol extend?
Post 21 Feb 2019, 17:13
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
Macro "define@struct" generates (with "local value" line) names for all the fields and iterates through them with "forward". In the "common" block parameter "value" is then replaced with a complete list of comma-separated generated names. Therefore you cannot skip a field in this macro.

One solution that comes to my mind would be to have the 4th parameter (your "extend") be a sub-list of unnamed fields that precede a named field. You could have outer "define@struct" filter the unnamed fields and enclose them in <> as 4th parameters for another macro that would generate names with "local value".

Another solution could be to define "struc name" and "macro name" with a single argument with "&" modifier and then iterate through two lists in parallel. It would end up a bit more complex, probably.
Post 21 Feb 2019, 17:33
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
Different ideas come to my mind too: define parallel sequence places@struct analogious to fields@struct that exist now, and then not include anonymous to that
Code:
                                irpv fields,field@struct \\\\{
                                        restore field@struct
                                 \\\\common
                                        restore @struct
                                        ;make@struct name,fields
                                        define fields@\#name fields \\\\}
                                irpv places,place@struct \\\\{
                                        restore place@struct
                                 \\\\common
                                        restore @struct
                                        make@struct name,fields@\#name,places
                                        define places@\#name places \\\\}    

But I couldn`t force them to end working variant.
at that version I thought extend should be outer of sequence:
macro define@struct name,extend,[field,type,def]
Post 21 Feb 2019, 18:04
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
I made a proof-of-concept with additional parameter per block for define@struct. I rebuilt make@struct like this:
Code:
macro make@struct name,[field,type,def] {
    common
        local CONVERTED,PREVIOUS,CURRENT
        define CONVERTED name
        define CURRENT 1
    forward
        PREVIOUS equ CURRENT
        define CURRENT 1
        local sub
        match , field \{ define CURRENT 2
                         make@substruct type,name,sub def \}
        match -, field \{ define CURRENT 0 \}
        match =1:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, < type def \}
        match =0:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, type def \}
        match =1:=1, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, , .#field, type, <def> \}
        match =0:=1, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED>, .#field, type, <def> \}
        match =1:=2, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, , ., sub, \}
        match =0:=2, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED>, ., sub, \}
        match =2, CURRENT \{ define CURRENT 1 \}
    common
        local anonymous
        match =0, CURRENT \{ CONVERTED equ CONVERTED>,anonymous,:, \}
        match converted, CONVERTED \{ define@struct converted \}
}    
This requires a change to how anonymous fields get defined by main "struct" macro:
Code:
macro struct name
 { virtual at 0
   define @struct
   field@struct equ name
   match child parent, name \{ restore field@struct
                               field@struct equ child,fields@\#parent \}
   sub@struct equ
   struc db [val] \{ \common define field@struct .,db,<val> \}
   struc dw [val] \{ \common define field@struct .,dw,<val> \}
   struc du [val] \{ \common define field@struct .,du,<val> \}
   struc dd [val] \{ \common define field@struct .,dd,<val> \}
   struc dp [val] \{ \common define field@struct .,dp,<val> \}
   struc dq [val] \{ \common define field@struct .,dq,<val> \}
   struc dt [val] \{ \common define field@struct .,dt,<val> \}
   struc rb count \{ define field@struct .,db,count dup (?) \}
   struc rw count \{ define field@struct .,dw,count dup (?) \}
   struc rd count \{ define field@struct .,dd,count dup (?) \}
   struc rp count \{ define field@struct .,dp,count dup (?) \}
   struc rq count \{ define field@struct .,dq,count dup (?) \}
   struc rt count \{ define field@struct .,dt,count dup (?) \}
   macro db [val] \{ \common define field@struct -,db,<val> \}
   macro dw [val] \{ \common define field@struct -,dw,<val> \}
   macro du [val] \{ \common define field@struct -,du,<val> \}
   macro dd [val] \{ \common define field@struct -,dd,<val> \}
   macro dp [val] \{ \common define field@struct -,dp,<val> \}
   macro dq [val] \{ \common define field@struct -,dq,<val> \}
   macro dt [val] \{ \common define field@struct -,dt,<val> \}
   macro rb count \{ define field@struct -,db,count dup (?) \}
   macro rw count \{ define field@struct -,dw,count dup (?) \}
   macro rd count \{ define field@struct -,dd,count dup (?) \}
   macro rp count \{ define field@struct -,dp,count dup (?) \}
   macro rq count \{ define field@struct -,dq,count dup (?) \}
   macro rt count \{ define field@struct -,dt,count dup (?) \}
   macro union \{ field@struct equ ,union,<
                  sub@struct equ union \}
   macro struct \{ field@struct equ ,substruct,<
                  sub@struct equ substruct \} }    
The anonymous fields get grouped into "anon" parameter given to define@struct:
Code:
macro define@struct name,[anon,field,type,def]    
All that remains is to use this additional parameter to insert definitions in the right places:
Code:
    struc name value \\{ \\local \\..base
    match , @struct \\\{ define field@struct .,name,<values> \\\}
    match no, @struct \\\{ label \\..base
   forward
     match any, anon \\\\{ irp anondef,any \\\\\{ anondef \\\\\}  \\\\} ; <- ADDED LINE
     match , value \\\\{ field type def \\\\}
     match any, value \\\\{ field type value
                            if ~ field eq .
                             rb sizeof.#name#field - ($-field)
                            end if \\\\}    
Code:
    macro name value \\{
    match , @struct \\\{ define field@struct -,name,<values> \\\}
    match no, @struct \\\{
   forward
     match any, anon \\\\{ irp anondef,any \\\\\{ anondef \\\\\}  \\\\} ; <- ADDED LINE
     match , value \\\\{ type def \\\\}
     match any, value \\\\{ \\\\local ..field
                           ..field = $
                           type value
                           if ~ field eq .
                            rb sizeof.#name#field - ($-..field)
                           end if \\\\}    
I have not tested this much, but it should at least give you a general idea of what I had in mind.
Post 21 Feb 2019, 21:15
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
Thanks.
It is the best gift on the eye of February23.
for my part, I will try to implement it in a working set of macros for structuring and have time to do everything until February 23.
I will share it here.
Post 22 Feb 2019, 09:23
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
You may need to add more <> encapsulation here and there. Definitely here:
Code:
        match =1:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, < <type def> \}
        match =0:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, <type def> \}    
Post 22 Feb 2019, 10:35
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
A bit late - today is 0:44 of February24.
But working set ready:
Code:
; Macroinstructions for defining data structures
def.rb equ db ; this could be placed out of struct.inc file
def.rw equ dw
def.rd equ dd
def.rp equ dp
def.rq equ dq
def.rt equ dt
datadef@directives equ db,dw,du,dd,dp,dq,dt
datarsv@directives equ rb,rw,rd,rp,rq,rt
;==============================================================
macro struct@overridedefs [datadef] {
        struc datadef [val:?] \{ \common define field@struct .,datadef,<val> \}
        macro datadef [val:?] \{ \common define field@struct -,datadef,<val> \} }
macro struct@overridersvs [datadef] {
        struc datadef count \{ \common define field@struct .,def.#datadef,count dup (?) \}
        macro datadef count \{ \common define field@struct -,def.#datadef,count dup (?) \} }
macro struct@restoredefs [datadef] {
        restruc datadef
        purge datadef }
;==============================================================
macro struct names {
        match name tail, names: \{
                virtual
                        db \`name
                        load initial@struct byte from $$
                        if initial@struct = '.'
                                display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
                                err
                        end if
                end virtual

                macro ends \\{
                        match , sub@struct \\\{
                                if $
                                        display 'Error: definition of ',\`name,' contains illegal instructions.',0Dh,0Ah
                                        err
                                end if

                                match any,datadef@directives \\\\{ struct@restoredefs any \\\\}
                                match any,datarsv@directives \\\\{ struct@restoredefs any \\\\}

                                purge union,struct,ends

                                irpv fields,field@struct \\\\{
                                        restore field@struct
                                 \\\\common
                                        restore @struct
                                        make@struct name,fields
                                        define fields@\#name fields \\\\}
                                end virtual \\\} ;end virtual must be after make@struct
                        match any, sub@struct \\\{
                                tmp@struct equ field@struct
                                restore field@struct
                                field@struct equ tmp@struct> \\\}
                        restore sub@struct \\}

                ;match :,tail \\{ \\}
                match parent:,tail \\{ field@struct equ fields@\\#parent \\} \}

        match any,datadef@directives \{ struct@overridedefs any \}
        match any,datarsv@directives \{ struct@overridersvs any \}
        irp datadef,union,struct \{
                macro datadef \\{
                        field@struct equ ,sub\#datadef,<
                        sub@struct equ sub\#datadef \\} \}

        define @struct
        sub@struct equ
        virtual at 0 }
;==============================================================
macro union names {
        struct names
        define @union }
;==============================================================
macro make@struct name,[field,type,def] {
    common
        local CONVERTED,PREVIOUS,CURRENT
        define CONVERTED name
        define CURRENT 1
    forward
        PREVIOUS equ CURRENT
        define CURRENT 1
        local sub
        match , field \{ define CURRENT 2
                         make@substruct type,name,sub def \}
        match -, field \{ define CURRENT 0 \}
        match =1:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, < <type def> \}
        match =0:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, <type def> \}
        match =1:=1, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, , .#field, type, <def> \}
        match =0:=1, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED>, .#field, type, <def> \}
        match =1:=2, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, , ., sub, \}
        match =0:=2, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED>, ., sub, \}
        match =2, CURRENT \{ define CURRENT 1 \}
    common
        local anonymous
        match =0, CURRENT \{ CONVERTED equ CONVERTED>,anonymous,:, \}
        match converted, CONVERTED \{
                match no, @union \\{ define@struct converted \\}
                match , @union \\{
                        restore @union
                        define@union converted \\} \} }
;==============================================================
macro define@union name,[anon,field,type,def] {
 forward
        match any, anon \{
                irp anondef,any \\{
                        \\local anonsize
                        virtual at 0
                                anondef
                                anonsize = $
                        end virtual
                        if anonsize > $
                                rb anonsize - $
                        end if
                        \\}  \}
        if ~ field eq .
                virtual at 0
                        name#field type def
                        sizeof.#name#field = $ - name#field
                end virtual
                if sizeof.#name#field > $
                        rb sizeof.#name#field - $
                end if
        else
                virtual at 0
                        label name#.#type
                        rb sizeof.#type
                end virtual
                if sizeof.#type > $
                        rb sizeof.#type - $
                end if
        end if
 common
        sizeof.#name = $
        restruc name
        struc name value \{
                \local \..base
                match , @struct \\{ define field@struct .,name,value \\}
                match no, @struct \\{
                        label \..base
                        last@union equ
 forward
                        match any, last@union \\\{
                        virtual at \..base
                                field type def
                        end virtual \\\}
                        match , last@union \\\{
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{ field type value \\\\} \\\}
                        last@union equ field
 common
                        if sizeof.#name > $ - \..base
                                rb sizeof.#name - ($ - \..base)
                        end if
                        label . at \..base \\}
        \}
        macro name value \{
                \local \..base
                match , @struct \\{ define field@struct -,name,value \\}
                match no, @struct \\{
                        label \..base
                        last@union equ
 forward
                        match , last@union \\\{ match any, value \\\\{ field type value \\\\} \\\}
                        last@union equ field
 common
                        if sizeof.#name > $ - \..base
                                rb sizeof.#name - ($ - \..base)
                        end if \\} \} }
;==============================================================
macro define@struct name,[anon,field,type,def] {
 common
        local list
        list equ
 forward
        local anonsize
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
        anonsize = $
        match any, anon \{ irp anondef,any \\{ anondef \\} \}
        anonsize = $-anonsize
;    END OF ASSUMPTION
        if ~ field eq .
                name#field type def
                sizeof.#name#field = $ - name#field
        else
                label name#.#type
                rb sizeof.#type
        end if
        local value
        match any, list \{ list equ list, \}
        list equ list <value>
 common
        sizeof.#name = $
        restruc name
        match values, list \{
                struc name value \\{
                        \\local \\..base
                        match , @struct \\\{ define field@struct .,name,<values> \\\}
                        match no, @struct \\\{
                                label \\..base
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                                rb anonsize
;    END of ASSUMPTION
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{
                                        field type value
                                        if ~ field eq .                           ; MAIN PURPOSE OF THEESE 3 LINES - REALISATION OF LEGACY ALIGNMENT STYLE IN STRUCTURES
                                                rb sizeof.#name#field - ($-field) ; BECAUSE ALIGNED FIELD PRECIDED WITH ANOTHER SHORTER SIZE FIELD - WE CAN EMULATE ALIGNMENT BY ADDING SEQUENCE OF ",?" TO END OF THAT SHORTER SIZE FIELD
                                        end if                                    ; 2ND PURPOSE - COMPARISON THAT DATA PASSED TO INITIALIZE STRUCTURE WILL FIT IN ITS MEMBERS; IN COMMON CASE MORE OPTIMAL SUCH COMPARISON FOR WHOLE STRUCTURE NOT PER FIELD
                                        \\\\}
 common

                                ;if $-\\..base-sizeof.#name                       ; IF WE REMOVE 3 LINES ABOVE COMMENTED AS LEGACY
                                ;        err                                      ; THEN WE MUST UNCOMMENT THESE 3 LINES
                                ;end if                                           ;
                                label . at \\..base \\\}
                \\}
                macro name value \\{
                        match , @struct \\\{ define field@struct -,name,<values> \\\}
                        match no, @struct \\\{
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                                rb anonsize
;    END of ASSUMPTION
                                match , value \\\\{ type def \\\\}
                                match any, value \\\\{
                                        \\\\local ..field
                                        ..field = $
                                        type value
                                        if ~ field eq .
                                                rb sizeof.#name#field - ($-..field)
                                        end if \\\\}
 common
                        \\\} \\} \} }
;==============================================================
macro enable@substruct {
        macro make@substruct substruct,parent,name,[field,type,def] \{
         \common
                \local CONVERTED,PREVIOUS,CURRENT
                define CONVERTED parent,name
                define CURRENT 1
         \forward
                PREVIOUS equ CURRENT
                define CURRENT 1
                \local sub
                match , field \\{
                        match any, type \\\{
                                define CURRENT 2
                                enable@substruct
                                make@substruct type,parent,sub def
                                purge make@substruct \\\} \\}
                match -, field \\{ define CURRENT 0 \\}
                match =1:=0, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED, < <type def> \\}
                match =0:=0, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED, <type def> \\}
                match =1:=1, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED, , .\#field, type, <def> \\}
                match =0:=1, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED>, .\#field, type, <def> \\}
                match =1:=2, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED, , ., sub, \\}
                match =0:=2, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED>, ., sub, \\}
                match =2, CURRENT \\{ define CURRENT 1 \\}
         \common
                \local anonymous
                match =0, CURRENT \\{ CONVERTED equ CONVERTED>,anonymous,:, \\}
                match converted, CONVERTED \\{ define@\#substruct converted \\} \} }
;==============================================================
enable@substruct
;==============================================================
macro define@subunion parent,name,[anon,field,type,def] {
 common
        virtual at parent#.#name
 forward
                match any, anon \{
                        irp anondef,any \\{
                                \\local anonsize
                                virtual at 0
                                        anondef
                                        anonsize = $
                                end virtual
                                if anonsize > $
                                        rb anonsize - $
                                end if
                                \\}  \}
                if ~ field eq .
                        virtual at parent#.#name
                                parent#field type def
                                sizeof.#parent#field = $ - parent#field
                        end virtual
                        if sizeof.#parent#field > $ - parent#.#name
                                rb sizeof.#parent#field - ($ - parent#.#name)
                        end if
                else
                        virtual at parent#.#name
                                label parent#.#type
                                type def
                        end virtual
                        label name#.#type at parent#.#name
                        if sizeof.#type > $ - parent#.#name
                                rb sizeof.#type - ($ - parent#.#name)
                        end if
                end if
 common
                sizeof.#name = $ - parent#.#name
        end virtual
        struc name value \{
                label .\#name
                last@union equ
 forward
                match any, last@union \\{
                        virtual at .\#name
                                field type def
                        end virtual \\}
                match , last@union \\{
                        match , value \\\{ field type def \\\}
                        match any, value \\\{ field type value \\\} \\}
                last@union equ field
 common
                rb sizeof.#name - ($ - .\#name) \}
        macro name value \{
                label .\#name
                last@union equ
 forward
                match , last@union \\{ match any, value \\\{ field type value \\\} \\}
                last@union equ field
 common
                rb sizeof.#name - ($ - .\#name) \} }
;==============================================================
macro define@substruct parent,name,[anon,field,type,def] {
 common
        virtual at parent#.#name
 forward
                local value,anonsize
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                anonsize = $
                match any, anon \{ irp anondef,any \\{ anondef \\} \}
                anonsize = $-anonsize
;    END OF ASSUMPTION
                if ~ field eq .
                        parent#field type def
                        sizeof.#parent#field = $ - parent#field
                else
                        label parent#.#type
                        rb sizeof.#type
                end if
 common
                sizeof.#name = $ - parent#.#name
        end virtual
        struc name value \{
                label .\#name
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                rb anonsize
;    END of ASSUMPTION
                match , value \\{ field type def \\}
                match any, value \\{
                        field type value
                        if ~ field eq .                             ; MAIN PURPOSE OF THEESE 3 LINES - REALISATION OF LEGACY ALIGNMENT STYLE IN STRUCTURES
                                rb sizeof.#parent#field - ($-field) ; BECAUSE ALIGNED FIELD PRECIDED WITH ANOTHER SHORTER SIZE FIELD - WE CAN EMULATE ALIGNMENT BY ADDING SEQUENCE OF ",?" TO END OF THAT SHORTER SIZE FIELD
                        end if \\}                                  ; 2ND PURPOSE - COMPARISON THAT DATA PASSED TO INITIALIZE STRUCTURE WILL FIT IN ITS MEMBERS; IN COMMON CASE MORE OPTIMAL SUCH COMPARISON FOR WHOLE STRUCTURE NOT PER FIELD
 common
                                ;if $-.\#name-sizeof.#name          ; IF WE REMOVE 3 LINES ABOVE COMMENTED AS LEGACY
                                ;        err                        ; THEN WE MUST UNCOMMENT THESE 3 LINES
                                ;end if                             ;
        \}
        macro name value \{
                \local ..anonymous
                ..anonymous name \} }    
Post 23 Feb 2019, 21:31
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 394
Location: Russian Federation, Sochi
ProMiNick
one more addition - reverse struct - rstruct:
needed definitions
Code:
datadef@directives equ db,dw,du,dd,dp,dq,dt
datarsv@directives equ rb,rw,rd,rp,rq,rt
algnmnt@directives equ
def.rb equ db
def.rw equ dw
def.rd equ dd
def.rp equ dp
def.rq equ dq
def.rt equ dt
db.align = 1
dw.align = 2
du.align = 2
dd.align = 4
dq.align = 8
    

helper macros:
Code:
macro struct@overridedefs [datadef] {
        struc datadef [val:?] \{ \common
                match any:no,force@alignment:@rstruct \\{ define field@struct -,align,datadef#.align \\}
                define field@struct .,datadef,<val> \}
        macro datadef [val:?] \{ \common
                match any:no,force@alignment:@rstruct \\{ define field@struct -,align,datadef#.align \\}
                define field@struct -,datadef,<val> \} }
;==============================================================
macro struct@overridersvs [datadef] {
        match ddd,def.#datadef \{
        struc datadef count \\{ \\common
                match any:no,force@alignment:@rstruct \\\{ define field@struct -,align,ddd\#.align \\\}
                define field@struct .,ddd,count dup (?) \\}
        macro datadef count \\{ \\common
                match any:no,force@alignment:@rstruct \\\{ define field@struct -,align,ddd\#.align \\\}
                define field@struct -,ddd,count dup (?) \\} \} }
;==============================================================
macro struct@overridealgn [datadef] {
        struc datadef amount:default.#datadef \{ define field@struct -,datadef,amount \}
        macro datadef amount:default.#datadef \{ define field@struct -,datadef,amount \} }
;==============================================================
macro struct@restoredefs [datadef] {
        restruc datadef
        purge datadef }     

struct macros itself:
Code:
; Macroinstructions for defining data structures

include 'HELPER/STRUCTHELPER.INC'

;==============================================================
; GLOBAL ASSUMPTIONS FOR THIS MACRO SET
; THERE IS NO PRACTICAL SENSE TO ENCLOSE IN UNION OR STRUCT NO ONE FIELD
; THERE IS NO PRACTICAL SENSE TO ENCLOSE IN SUBUNION OR SUBSTRUCT ONLY 1 FIELD OR EVEN NO ONE
; THERE IS NO PRACTICAL SENSE TO ENCLOSE IN SUBUNION ONLY UNNAMED FIELDS
;==============================================================

macro struct definition {
        match name tail, definition: \{
                virtual
                        db \`name
                        load initial@struct byte from $$
                        if initial@struct = '.'
                                display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
                                err
                        end if
                end virtual

                macro ends \\{
                        match , sub@struct \\\{
                                if $
                                        display 'Error: definition of ',\`name,' contains illegal instructions.',0Dh,0Ah
                                        err
                                end if

                                match any,datadef@directives \\\\{ struct@restoredefs any \\\\}
                                match any,datarsv@directives \\\\{ struct@restoredefs any \\\\}
                                match any,algnmnt@directives \\\\{ struct@restorealgn any \\\\}

                                purge union,struct,rstruct,ends

                                irpv fields,field@struct \\\\{
                                        restore field@struct
                                 \\\\common
                                        restore @struct
                                        make@struct name,fields
                                        define fields@\#name fields \\\\}
                                end virtual \\\} ;end virtual must be after make@struct
                        match any, sub@struct \\\{
                                tmp@struct equ field@struct
                                restore field@struct
                                field@struct equ tmp@struct> \\\}
                        restore sub@struct \\}

                ;match :,tail \\{ \\}
                match parent:,tail \\{ field@struct equ fields@\\#parent \\} \}

        match any,datadef@directives \{ struct@overridedefs any \}
        match any,datarsv@directives \{ struct@overridersvs any \}
        match any,algnmnt@directives \{ struct@overridealgn any \}
        irp datadef,union,struct,rstruct \{
                macro datadef \\{
                        field@struct equ ,sub\#datadef,<
                        sub@struct equ sub\#datadef \\} \}

        define @struct
        sub@struct equ
        virtual at 0 }
;==============================================================
macro union definition {
        struct definition
        define @union }
;==============================================================
macro rstruct definition {
        struct definition
        define @rstruct }
;==============================================================
macro make@struct name,[field,type,def] {
    common
        local CONVERTED,PREVIOUS,CURRENT
        define CONVERTED name
        define CURRENT 1
    forward
        PREVIOUS equ CURRENT
        define CURRENT 1
        local sub
        match , field \{ define CURRENT 2
                         make@substruct type,name,sub def \}
        match -, field \{ define CURRENT 0 \}
        match =1:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED, < <type def>                                           \}
        match =0:=0, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED              , <type def>                            \}
        match =1:=1, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED,                           , .#field,  type, <def> \}
        match =0:=1, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED                           >, .#field,  type, <def> \}
        match =1:=2, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED,                           , .,        sub,        \}
        match =0:=2, PREVIOUS:CURRENT \{ CONVERTED equ CONVERTED                           >, .,        sub,        \}
        match =2, CURRENT             \{ define CURRENT 1 \}
    common
        local anonymous
        match =0, CURRENT             \{ CONVERTED equ CONVERTED                           >, anonymous,:,          \}
        match converted, CONVERTED \{
                match no:no, @union:@rstruct \\{ define@struct converted \\}
                match no:, @union:@rstruct \\{
                        restore @rstruct
                        define@rstruct converted \\}
                match :no, @union:@rstruct \\{
                        restore @union
                        define@union converted \\} \} }
;==============================================================
macro define@union name,[anon,field,type,def] {
 forward
        match any, anon \{
                irp anondef,any \\{
                        \\local anonsize
                        virtual at 0
                                anondef
                                anonsize = $
                        end virtual
                        if anonsize > $
                                rb anonsize - $
                        end if
                        \\}  \}
        if ~ field eq .
                virtual at 0
                        name#field type def
                        sizeof.#name#field = $ - name#field
                end virtual
                if sizeof.#name#field > $
                        rb sizeof.#name#field - $
                end if
        else
                virtual at 0
                        label name#.#type
                        rb sizeof.#type
                end virtual
                if sizeof.#type > $
                        rb sizeof.#type - $
                end if
        end if
 common
        sizeof.#name = $
        restruc name
        struc name value \{
                \local \..base
                match , @struct \\{ define field@struct .,name,value \\}
                match no, @struct \\{
                        label \..base
                        last@union equ
 forward
                        match any, last@union \\\{
                        virtual at \..base
                                field type def
                        end virtual \\\}
                        match , last@union \\\{
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{ field type value \\\\} \\\}
                        last@union equ field
 common
                        if sizeof.#name > $ - \..base
                                rb sizeof.#name - ($ - \..base)
                        end if
                        label . at \..base \\}
        \}
        macro name value \{
                \local \..base
                match , @struct \\{ define field@struct -,name,value \\}
                match no, @struct \\{
                        label \..base
                        last@union equ
 forward
                        match , last@union \\\{ match any, value \\\\{ field type value \\\\} \\\}
                        last@union equ field
 common
                        if sizeof.#name > $ - \..base
                                rb sizeof.#name - ($ - \..base)
                        end if \\} \} }
;==============================================================
macro define@rstruct name,[anon,field,type,def] {
 common
        local list,..start,..size
        list equ
        virtual at -..size
                ..start:
 forward
                local anonsize
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                anonsize = $
                match any, anon \{ irp anondef,any \\{ anondef \\} \}
                anonsize = $-anonsize
;    END OF ASSUMPTION
                if ~ field eq .
                        name#field type def
                        sizeof.#name#field = $ - name#field
                else
                        label name#.#type
                        rb sizeof.#type
                end if
                local value
                match any, list \{ list equ list, \}
                list equ list <value>
 common
                ..size = $ - ..start
        end virtual
        sizeof.#name = ..size
        restruc name
        match values, list \{
                struc name value \\{
                        match , @struct \\\{ define field@struct .,name,<values> \\\}
                        match no, @struct \\\{
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                                rb anonsize
;    END of ASSUMPTION
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{
                                        field type value
                                        if ~ field eq .                           ; MAIN PURPOSE OF THEESE 3 LINES - REALISATION OF LEGACY ALIGNMENT STYLE IN STRUCTURES
                                                rb sizeof.#name#field - ($-field) ; BECAUSE ALIGNED FIELD PRECIDED WITH ANOTHER SHORTER SIZE FIELD - WE CAN EMULATE ALIGNMENT BY ADDING SEQUENCE OF ",?" TO END OF THAT SHORTER SIZE FIELD
                                        end if                                    ; 2ND PURPOSE - COMPARISON THAT DATA PASSED TO INITIALIZE STRUCTURE WILL FIT IN ITS MEMBERS; IN COMMON CASE MORE OPTIMAL SUCH COMPARISON FOR WHOLE STRUCTURE NOT PER FIELD
                                        \\\\}
 common

                                ;if $-\\..base-sizeof.#name                       ; IF WE REMOVE 3 LINES ABOVE COMMENTED AS LEGACY
                                ;        err                                      ; THEN WE MUST UNCOMMENT THESE 3 LINES
                                ;end if                                           ;
                                label . \\\}
                \\}
                macro name value \\{
                        \\local anonymous
                        match , @struct \\\{ define field@struct -,name,<values> \\\}
                        match no, @struct \\\{ anonymous name value \\\} \\} \} }
;==============================================================
macro define@struct name,[anon,field,type,def] {
 common
        local list
        list equ
 forward
        local anonsize
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
        anonsize = $
        match any, anon \{ irp anondef,any \\{ anondef \\} \}
        anonsize = $-anonsize
;    END OF ASSUMPTION
        if ~ field eq .
                name#field type def
                sizeof.#name#field = $ - name#field
        else
                label name#.#type
                rb sizeof.#type
        end if
        local value
        match any, list \{ list equ list, \}
        list equ list <value>
 common
        sizeof.#name = $
        restruc name
        match values, list \{
                struc name value \\{
                        \\local \\..base
                        match , @struct \\\{ define field@struct .,name,<values> \\\}
                        match no, @struct \\\{
                                label \\..base
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                                rb anonsize
;    END of ASSUMPTION
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{
                                        field type value
                                        if ~ field eq .                           ; MAIN PURPOSE OF THEESE 3 LINES - REALISATION OF LEGACY ALIGNMENT STYLE IN STRUCTURES
                                                rb sizeof.#name#field - ($-field) ; BECAUSE ALIGNED FIELD PRECIDED WITH ANOTHER SHORTER SIZE FIELD - WE CAN EMULATE ALIGNMENT BY ADDING SEQUENCE OF ",?" TO END OF THAT SHORTER SIZE FIELD
                                        end if                                    ; 2ND PURPOSE - COMPARISON THAT DATA PASSED TO INITIALIZE STRUCTURE WILL FIT IN ITS MEMBERS; IN COMMON CASE MORE OPTIMAL SUCH COMPARISON FOR WHOLE STRUCTURE NOT PER FIELD
                                        \\\\}
 common

                                ;if $-\\..base-sizeof.#name                       ; IF WE REMOVE 3 LINES ABOVE COMMENTED AS LEGACY
                                ;        err                                      ; THEN WE MUST UNCOMMENT THESE 3 LINES
                                ;end if                                           ;
                                label . at \\..base \\\}
                \\}
                macro name value \\{
                        \\local anonymous
                        match , @struct \\\{ define field@struct -,name,<values> \\\}
                        match no, @struct \\\{ anonymous name value \\\} \\} \} }
;==============================================================
macro enable@substruct {
        macro make@substruct substruct,parent,name,[field,type,def] \{
         \common
                \local CONVERTED,PREVIOUS,CURRENT
                define CONVERTED parent,name
                define CURRENT 1
         \forward
                PREVIOUS equ CURRENT
                define CURRENT 1
                \local sub
                match , field \\{
                        match any, type \\\{
                                define CURRENT 2
                                enable@substruct
                                make@substruct type,parent,sub def
                                purge make@substruct \\\} \\}
                match -, field \\{ define CURRENT 0 \\}
                match =1:=0, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED, < <type def>                                      \\}
                match =0:=0, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED              , <type def>                          \\}
                match =1:=1, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED,                           , .\#field, type, <def> \\}
                match =0:=1, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED                           >, .\#field, type, <def> \\}
                match =1:=2, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED,                           , .,        sub,        \\}
                match =0:=2, PREVIOUS:CURRENT \\{ CONVERTED equ CONVERTED                           >, .,        sub,        \\}
                match =2, CURRENT \\{ define CURRENT 1 \\}
         \common
                \local anonymous
                match =0, CURRENT \\{ CONVERTED equ CONVERTED                                       >,anonymous, :,          \\}
                match converted, CONVERTED \\{ define@\#substruct converted \\} \} }
;==============================================================
enable@substruct
;==============================================================
macro define@subunion parent,name,[anon,field,type,def] {
 common
        virtual at parent#.#name
 forward
                match any, anon \{
                        irp anondef,any \\{
                                \\local anonsize
                                virtual at 0
                                        anondef
                                        anonsize = $
                                end virtual
                                if anonsize > $
                                        rb anonsize - $
                                end if
                                \\}  \}
                if ~ field eq .
                        virtual at parent#.#name
                                parent#field type def
                                sizeof.#parent#field = $ - parent#field
                        end virtual
                        if sizeof.#parent#field > $ - parent#.#name
                                rb sizeof.#parent#field - ($ - parent#.#name)
                        end if
                else
                        virtual at parent#.#name
                                label parent#.#type
                                type def
                        end virtual
                        label name#.#type at parent#.#name
                        if sizeof.#type > $ - parent#.#name
                                rb sizeof.#type - ($ - parent#.#name)
                        end if
                end if
 common
                sizeof.#name = $ - parent#.#name
        end virtual
        struc name value \{
                label .\#name
                last@union equ
 forward
                match any, last@union \\{
                        virtual at .\#name
                                field type def
                        end virtual \\}
                match , last@union \\{
                        match , value \\\{ field type def \\\}
                        match any, value \\\{ field type value \\\} \\}
                last@union equ field
 common
                rb sizeof.#name - ($ - .\#name) \}
        macro name value \{
                label .\#name
                last@union equ
 forward
                match , last@union \\{ match any, value \\\{ field type value \\\} \\}
                last@union equ field
 common
                rb sizeof.#name - ($ - .\#name) \} }
;==============================================================
macro define@subrstruct parent,name,[anon,field,type,def] {
 common
        local ..start,..size
        virtual at parent#.#name-..size
                ..start:
 forward
                local value,anonsize
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                anonsize = $
                match any, anon \{ irp anondef,any \\{ anondef \\} \}
                anonsize = $-anonsize
;    END OF ASSUMPTION
                if ~ field eq .
                        parent#field type def
                        sizeof.#parent#field = $ - parent#field
                else
                        label parent#.#type
                        rb sizeof.#type
                end if
 common
                ..size = $ - ..start
                sizeof.#name = ..size
        end virtual
        struc name value \{
                label .\#name
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                rb anonsize
;    END of ASSUMPTION
                match , value \\{ field type def \\}
                match any, value \\{
                        field type value
                        if ~ field eq .                             ; MAIN PURPOSE OF THEESE 3 LINES - REALISATION OF LEGACY ALIGNMENT STYLE IN STRUCTURES
                                rb sizeof.#parent#field - ($-field) ; BECAUSE ALIGNED FIELD PRECIDED WITH ANOTHER SHORTER SIZE FIELD - WE CAN EMULATE ALIGNMENT BY ADDING SEQUENCE OF ",?" TO END OF THAT SHORTER SIZE FIELD
                        end if \\}                                  ; 2ND PURPOSE - COMPARISON THAT DATA PASSED TO INITIALIZE STRUCTURE WILL FIT IN ITS MEMBERS; IN COMMON CASE MORE OPTIMAL SUCH COMPARISON FOR WHOLE STRUCTURE NOT PER FIELD
 common
                                ;if $-.\#name-sizeof.#name          ; IF WE REMOVE 3 LINES ABOVE COMMENTED AS LEGACY
                                ;        err                        ; THEN WE MUST UNCOMMENT THESE 3 LINES
                                ;end if                             ;
        \}
        macro name value \{
                \local ..anonymous
                ..anonymous name \} }
;==============================================================
macro define@substruct parent,name,[anon,field,type,def] {
 common
        virtual at parent#.#name
 forward
                local value,anonsize
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                anonsize = $
                match any, anon \{ irp anondef,any \\{ anondef \\} \}
                anonsize = $-anonsize
;    END OF ASSUMPTION
                if ~ field eq .
                        parent#field type def
                        sizeof.#parent#field = $ - parent#field
                else
                        label parent#.#type
                        rb sizeof.#type
                end if
 common
                sizeof.#name = $ - parent#.#name
        end virtual
        struc name value \{
                label .\#name
 forward
;!!! WE MAKING ASSUMPTION THAT UNNAMED FIELDS ARE JUST RESERVE SPACE
                rb anonsize
;    END of ASSUMPTION
                match , value \\{ field type def \\}
                match any, value \\{
                        field type value
                        if ~ field eq .                             ; MAIN PURPOSE OF THEESE 3 LINES - REALISATION OF LEGACY ALIGNMENT STYLE IN STRUCTURES
                                rb sizeof.#parent#field - ($-field) ; BECAUSE ALIGNED FIELD PRECIDED WITH ANOTHER SHORTER SIZE FIELD - WE CAN EMULATE ALIGNMENT BY ADDING SEQUENCE OF ",?" TO END OF THAT SHORTER SIZE FIELD
                        end if \\}                                  ; 2ND PURPOSE - COMPARISON THAT DATA PASSED TO INITIALIZE STRUCTURE WILL FIT IN ITS MEMBERS; IN COMMON CASE MORE OPTIMAL SUCH COMPARISON FOR WHOLE STRUCTURE NOT PER FIELD
 common
                                ;if $-.\#name-sizeof.#name          ; IF WE REMOVE 3 LINES ABOVE COMMENTED AS LEGACY
                                ;        err                        ; THEN WE MUST UNCOMMENT THESE 3 LINES
                                ;end if                             ;
        \}
        macro name value \{
                \local ..anonymous
                ..anonymous name \} }    
Post 21 May 2019, 15:11
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-2019, Tomasz Grysztar.

Powered by rwasa.