flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Fasm 1.73 How 'struct' macro determine what is interface ?

Author
Thread Post new topic Reply to topic
Roman



Joined: 21 Apr 2012
Posts: 1792
Roman 31 Jul 2019, 13:08
I need macro that could determine interface.

For example i have struct:

Code:
Interface A,\
    Run,Stop,Destroy

struct Some
x dd 0
procX Interface A.Run
y dd 0
procY Interface A.Run
ends
    


Macro must determine interface and then do Call [SomeProc+procX]
Let say macroX
macroX do this:
Code:
macroX Some.x,10
macroX Some.procX,2
    

generate code:
Code:
mov [Some.x],10 ;first macroX

push 2 ;second macroX
call [SomeProcsTab+Some.procX]
    
Post 31 Jul 2019, 13:08
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 01 Aug 2019, 00:30
What for things that makes code completely unreadable?
Thouself first will start using ubnormal uncensored lexic when thou tryed to code in thou suggested syntax.

Code:
struc Atbl a,b,c {
        .Run dd a
        .Stop dd b
        .Destroy dd c }

SomeProcsTab Atbl

struc Interface name { \.#. equ :name }

macroX op1,[op2] {
common  local ..tmp
        ..tmp = $
        match :methd, op1 \{
reverse
                pushd   op2
common
                call    [methd] \}
        if ..tmp=$
                mov     [op1], op2
        end if }


struct Some
 x dd 0
 procX Interface SomeProcsTab.Run
 y dd 0
 procY Interface SomeProcsTab.Run
ends      
Post 01 Aug 2019, 00:30
View user's profile Send private message Send e-mail Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1792
Roman 01 Aug 2019, 06:24
Not work !
Many errors !
Struct some.procX ilegal.
Did you test you macro ?
Post 01 Aug 2019, 06:24
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 01 Aug 2019, 11:01
Code:
struc Atbl a:0,b:0,c:0 {
        .Run dd a
        .Stop dd b
        .Destroy dd c }

struc label def& { label . def }

struc Interface name { define field@struct .,label dword at name, }



macro macroX op1,[op2] {
common  local ..tmp
        ..tmp = $
        match =:methd, op1 {
        irp op,op2
\\reverse
                pushd   op2
common
                call    [methd] \}
        if ..tmp=$
                mov     [op1], op2
        end if }



struct Some
 x dd 0
 procX Interface SomeProcsTab.Run
 y dd 0
 procY Interface SomeProcsTab.Run
ends


SomeProcsTab Atbl
Y Some

macroX Y.x, 10
macroX Y.procX, 2     
Post 01 Aug 2019, 11:01
View user's profile Send private message Send e-mail Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1792
Roman 01 Aug 2019, 13:16
Undefined error Y.procX
Post 01 Aug 2019, 13:16
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 01 Aug 2019, 14:23
Code:
; Macroinstructions for defining data structures

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 \local anonymous
                     define field@struct anonymous,db,<val> \}
   macro dw [val] \{ \common \local anonymous
                     define field@struct anonymous,dw,<val> \}
   macro du [val] \{ \common \local anonymous
                     define field@struct anonymous,du,<val> \}
   macro dd [val] \{ \common \local anonymous
                     define field@struct anonymous,dd,<val> \}
   macro dp [val] \{ \common \local anonymous
                     define field@struct anonymous,dp,<val> \}
   macro dq [val] \{ \common \local anonymous
                     define field@struct anonymous,dq,<val> \}
   macro dt [val] \{ \common \local anonymous
                     define field@struct anonymous,dt,<val> \}
   macro rb count \{ \local anonymous
                     define field@struct anonymous,db,count dup (?) \}
   macro rw count \{ \local anonymous
                     define field@struct anonymous,dw,count dup (?) \}
   macro rd count \{ \local anonymous
                     define field@struct anonymous,dd,count dup (?) \}
   macro rp count \{ \local anonymous
                     define field@struct anonymous,dp,count dup (?) \}
   macro rq count \{ \local anonymous
                     define field@struct anonymous,dq,count dup (?) \}
   macro rt count \{ \local anonymous
                     define field@struct anonymous,dt,count dup (?) \}
   macro union \{ field@struct equ ,union,<
                  sub@struct equ union \}
   macro struct \{ field@struct equ ,substruct,<
                  sub@struct equ substruct \} }

macro ends
 { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
                         restruc rb,rw,rd,rp,rq,rt
                         purge db,dw,du,dd,dp,dq,dt
                         purge rb,rw,rd,rp,rq,rt
                         purge union,struct
                         irpv fields,field@struct \\{ restore field@struct
                                                      \\common define fields@struct fields \\}
                         match name tail,fields@struct, \\{ if $
                                                            display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
                                                            err
                                                            end if \\}
                         match name=,fields,fields@struct \\{ restore @struct
                                                              make@struct name,fields
                                                              define fields@\\#name fields \\}
                         end virtual \}
   match any, sub@struct \{ tmp@struct equ field@struct
                            restore field@struct
                            field@struct equ tmp@struct> \}
   restore sub@struct }

macro make@struct name,[field,type,def]
 { common
    local define
    define equ name
   forward
    local sub
    match , field \{ make@substruct type,name,sub def
                     define equ define,.,sub, \}
    match any, field \{ define equ define,.#field,type,<def> \}
   common
    match fields, define \{ define@struct fields \} }

macro define@struct name,[field,type,def]
 { common
    virtual
    db `name
    load initial@struct byte from 0
    if initial@struct = '.'
    display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
    err
    end if
    end virtual
    local list
    list equ
   forward
    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
     match , value \\\\{ field type def \\\\}
     match any, value \\\\{ field type value
                            if ~ field eq .
                             rb sizeof.#name#field - ($-field)
                            end if \\\\}
   common label . at \\..base \\\}
   \\}
    macro name value \\{
    match , @struct \\\{ \\\local anonymous
                                  define field@struct anonymous,name,<values> \\\}
    match no, @struct \\\{
   forward
     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 define
        define equ parent,name
       \forward
        \local sub
        match , field \\{ match any, type \\\{ enable@substruct
                                               make@substruct type,parent,sub def
                                               purge make@substruct
                                               define equ define,.,sub, \\\} \\}
        match any, field \\{ define equ define,.\#field,type,<def> \\}
       \common
        match fields, define \\{ define@\#substruct fields \\} \} }

enable@substruct

macro define@union parent,name,[field,type,def]
 { common
    virtual at parent#.#name
   forward
    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] \{ \common
    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] \{ \common \local ..anonymous
                          ..anonymous name value \} }

macro define@substruct parent,name,[field,type,def]
 { common
    virtual at parent#.#name
   forward
    local value
    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
     match , value \\{ field type def \\}
     match any, value \\{ field type value
                          if ~ field eq .
                           rb sizeof.#parent#field - ($-field)
                          end if \\}
   common \}
    macro name value \{ \local ..anonymous
                        ..anonymous name \} }


struc Atbl a:0,b:0,c:0 {
        .Run dd a
        .Stop dd b
        .Destroy dd c }

struc label def& { label . def }

struc Interface name { define field@struct .,label dword at name, }



macro macroX op1,[op2] {
common  local ..tmp
        ..tmp = $
        match =:methd, op1 {
        irp op,op2
\\reverse
                pushd   op2
common
                call    [methd] \}
        if ..tmp=$
                mov     [op1], op2
        end if }



struct Some
 x dd 0
 procX Interface SomeProcsTab.Run
 y dd 0
 procY Interface SomeProcsTab.Run
ends


SomeProcsTab Atbl
Y Some

macroX Y.x, 10
macroX Y.procX, 2     


2 passes 38 bytes

compiled with fasmw 1.73.13 (1.73.06) same result no errors
I only add struct.inc content from official fasmw package infront of previous post (because struct used in code).

In example above macroX - is bad coding style (because it is hiding difference between mov & call in macro internals).

But method definition via pointing to another address is good coding style: methods of structure Some - are not part of that structure in real time but in design time methods are descendants of structure Some - it is pseudo OOP(it is much faster than true OOP). (dependances would be resolved in compilation time - so compilation itself will be slower, but when user will execute application it will work much faster in amount of time that needed for resolving object dependances in real time).
Post 01 Aug 2019, 14:23
View user's profile Send private message Send e-mail Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1792
Roman 01 Aug 2019, 15:28
IDA show two mov !
But not push and call on second macro.
Post 01 Aug 2019, 15:28
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 799
Location: Russian Federation, Sochi
ProMiNick 01 Aug 2019, 16:22
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

sizeof.PTR =4
struc PTR [value:?] { common . dd value }
macro PTR [value:?] { common dd value }


; Macroinstructions for defining data structures

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 }

;==============================================================
; 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 .
                sizeof.#name#field = $
                name#field type def
                sizeof.#name#field = $ - sizeof.#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 \} }

struc Atbl a:0,b:0,c:0 {
        .Run dd a
        .Stop dd b
        .Destroy dd c }

struc label def& { label . def }

struc Interface name { define field@struct .,equ :name, }



macro macroX op1,[op2] {
common  local ..tmp
        ..tmp = $
        match =:methd, op1 \{
reverse
                pushd   op2
common
                call    [methd] \}
        if ..tmp=$
                mov     [op1], op2
        end if }



struct Some
 x dd 0
 procX Interface SomeProcsTab.Run
 y dd 0
 procY Interface SomeProcsTab.Run
ends


SomeProcsTab Atbl
Y Some

use32

macroX Y.x, 10
macroX Y.procX, 2       


copilation warned about 2nd line:
Code:
                name#field type def
                sizeof.#name#field = $ - name#field ; sizeof.Some.procX=$-:SomeProcsTab.Run    
so I replaced them with
Code:
                sizeof.#name#field = $
                name#field type def
                sizeof.#name#field = $ - sizeof.#name#field    

not best approach but workable.

difference with previous
Code:
struc Interface name { define field@struct .,equ :name, }; we need to make colon, and because of that patches inside struct itself become needed    
Post 01 Aug 2019, 16:22
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.