flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > [fasmg]namespace:local alias import/cleanup of struct types?

Author
Thread Post new topic Reply to topic
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
In a big namespace-ized application, in a part of the source code I would like to use "short" identifiers from a module somewhere else in the source: for label symbols, I can use "define" and "restore" to create and destroy those "short" local aliases, but I don't see how to do the same thing with a struct type which is declared into a "virtual at 0" section: once I created an short local "alias" for a struct type in a "virtual at 0", I cannot cleanup this local alias with "restore"/"purge"/"restruct". What do I miss?
Post 02 Aug 2021, 01:25
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3282
Location: vpcmipstrm
bitRAKE
Maybe this consolidated table will help:
https://board.flatassembler.net/topic.php?p=215915#215915

RESTRUC does bring back previous value on STRUC.

Maybe post a small example that is not working as expected?
(Maybe you are using "struct" which is a macro in stead of STRUC?)

_________________
¯\(°_o)/¯ unlicense.org
Post 02 Aug 2021, 03:33
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
I am trying to import in a section of code a struct type using short aliases, namely before this code section I would create the short aliases, then after this code section clear those short aliases (which could be used, maybe for other things in other sections of the code). Aliases could come for several other modules and namespaces.

In struct, there are 2 separate things: the "struc" part then the "virtual at 0".
For instance, I have in the global namespace linux.stat_t, namely a STRUC labeled macroinstruction, and label/constant "linux.stat_t" (virtual at 0).
In a code section, I am trying to instanciate a "linux.stat_t" but with the local short "stat_t" alias. I can create a "stat_t" STRUC using "linux.stat_t" STRUC. Then after the code section I can remove the temporary "stat_t" STRUC with a "stat_t" RESTRUCT.
I can create a "stat_t" label/constant in a "virtual at 0" section in order to get a the "stat_t" field offsets, but I cannot remove it since it is a label/constant. I tried to "define stat_t linux.stat_t" in the section code, it does not work as it seems it does not deal with all types of symbols.
I am probably not using fasm namespaces properly.
Post 02 Aug 2021, 13:38
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7918
Location: Kraków, Poland
Tomasz Grysztar
You could probably be able to use some of the internal metadata of STRUCT macro in order to generate temporary aliases as variables that you could then automatically RESTORE.

However, I see another simple trick that may do the job, but that depends on your use cases. You can use MATCH directive to do some simple text replacement pre-processing on a section of source:
Code:
match stat_t, linux.stat_t
    ; here all the code that requires the alias
end match    
Post 02 Aug 2021, 14:54
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
I am trying to leverage the fasmg namespace system for this use case, namely I made those 'code sections', fasmg namespaces.
Then prior to such a 'code section', I am trying to import everything I need from the other 'code sections'.
Then I realized that for structs (presuming the nasty case of nested structs) which are built from different 'code sections', baw... I would need to reimport all the hierarchy of structs into the 'code section' namespace with proper aliases.
All that to be able to get computed field offsets from the bare struct type (virtual at 0), or the field labels for an instance of this very struct type.
Post 02 Aug 2021, 17:18
View user's profile Send private message Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
I tried to use match as a text preprocessor like this:
Code:
include 'format/format.inc'
format.elf64
macro struct name
        macro end.struct!
                        end namespace
                esc end struc
                virtual at 0
                        name name
                        sizeof.name = $
                end virtual
                purge end.struct
        end macro
                esc struc name
                        label . : sizeof.name
                        namespace .
end macro

;foo=0
struct foo.a_t
        field_0 rq 1
end struct
match a_t, foo.a_t
struct bar.b_t
        field_0 rq 2
        field_1 a_t
end struct
end match
section '.bss' writeable align 16
    


It does not work unless the foo symbol is instanciated, namely with a
Code:
label foo    
or
Code:
foo=0    


This led me to ask how the walk thru the namespace hierarchy is done in regards of namespace symbol instanciation and types?

Additionally, I tried to wrap the "match" instruction into a macro... and it does not work, I guess it is related on implicit context/state thingies I don't "see":
Code:
macro map to,from
     macro end.map
         esc end match
         purge end.map
     end macro
         esc match to,from
end macro
    
Post 03 Aug 2021, 15:34
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7918
Location: Kraków, Poland
Tomasz Grysztar
sylware wrote:
This led me to ask how the walk thru the namespace hierarchy is done in regards of namespace symbol instanciation and types?
The symbol lookup starts from the most specific (local) - from the current namespace and case-sensitive symbols, then case-insensitive symbols in the same namespace, and then proceeds to scan the consecutive parent namespaces, up to the root. If no defined symbol is found anywhere, it defaults back to the case-sensitive symbol in current namespace (even when it is undefined).

Also, when identifier has multiple segments (separated with dot), all these segments except for the last are treated as expression-class (symbols defined with things like "=", EQU, LABEL, etc.). So if you are looking for an instruction "foo.bar", it finds the most local expression-class symbol "foo" to get the namespace, and then looks for an instruction-class symbol "bar" in that namespace. See also section 5 of the manual.

sylware wrote:
Additionally, I tried to wrap the "match" instruction into a macro... and it does not work, I guess it is related on implicit context/state thingies I don't "see": (...)
Try ESC OUTSCOPE idiom as in the example in the manual. Without it the replacement defined by MATCH is limited to the scope of the macro.

This might actually be easier with CALM, but that's another story.
Post 03 Aug 2021, 16:40
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
allright, I read the manual, but still struggle to build a mental picture of fasm model and behaviour.
Ok, foo must have a symbol of expression class instanciated in order to allow finding any descendant, but we can create descendants anyway.
I don't picture what is the difference between the macro "scope" and any other "scope", and why "outscope" must be added. I guess more manual reading.
Calm seems more explicit with a simpler model, I may be wrong though.
Post 03 Aug 2021, 17:57
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7918
Location: Kraków, Poland
Tomasz Grysztar
sylware wrote:
Ok, foo must have a symbol of expression class instanciated in order to allow finding any descendant, but we can create descendants anyway.
It is not required to have "foo" defined to access its namespace, but then when you enter a different namespace, "foo" is going to refer to the symbol in the local namespace, leaving you with no ability to refer to that earlier "foo". Therefore to make "foo" always refer to the same thing, you should define it as global symbol (and not define a local one with the same name, as the local one would take precedence).

sylware wrote:
I don't picture what is the difference between the macro "scope" and any other "scope", and why "outscope" must be added.
This is a separete issue, as it not related to namespaces, but to preprocessing. A text replacement defined with directives like MATCH, ITERATE, etc. is performed in the block of text, which is the "scope" for these operations. For example, if inside the block you INCLUDE a file, the contents of that file is not in the scope of the text that has the replacement applied (even though it also resides between MATCH and END MATCH). Similarly, the scope never passes through macro boundaries - so when you start MATCH inside a macro, then outside of that macro the text replacements no longer apply, even when END MATCH has not yet been reached. By using OUTSCOPE you tell the preprocessor that text replacements defined by a specified directive should instead apply in the outer scope, that is outside of the macro you are currently in.

sylware wrote:
Calm seems more explicit with a simpler model, I may be wrong though.
Yes, with CALM this all becomes explicit, because CALM replaces the preprocessing step mentioned above, and you manually prepare lines to be assembled.
Post 04 Aug 2021, 09:16
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
And I guess each scope has a set of various namespace trees attached to it. Got my hands on your draft document on fasm internals, but indeed the task seems huge.

That said, to import(instanciate) a label in a namespace from another namespace I guess the "right way"(TM), would be:
label foo.label1 at bar.label2
instead of (even if it works):
foo.label1 = bar.label2
Post 04 Aug 2021, 12:41
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7918
Location: Kraków, Poland
Tomasz Grysztar
sylware wrote:
And I guess each scope has a set of various namespace trees attached to it.
No, what I meant by "scope" applies only to parameter-replacement preprocessing, it is completely independent from the namespaces tree.

sylware wrote:
Got my hands on your draft document on fasm internals, but indeed the task seems huge.
Such document only exists for fasm 1, which is a different architecture (for example, it has no namespaces, and preprocessing is done as a separate stage on the entire source text).
Post 04 Aug 2021, 13:56
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
I guess I have the tools to start coding my namespace-ized program. I'll see then if I hit some "bumps" along the road.

Out of curiosity, I had a look at calm instructions, and with my primitive understanding of fasmg model, I was puzzled by 2 things:
how with a calm instruction, to process several "lines" disabling the implicit assembly stage? Namely between 2 markers to disable the "implicit" assembly of "lines" in order to let calm instructions "preprocess" them and then "explicitely" pass them to the assembly stage.

Then, in a calm instruction, I don't know how to perform the same thing than the "macro match" with the "calm match", namely simple identifier substitution.
Post 05 Aug 2021, 13:06
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7918
Location: Kraków, Poland
Tomasz Grysztar
sylware wrote:
how with a calm instruction, to process several "lines" disabling the implicit assembly stage? Namely between 2 markers to disable the "implicit" assembly of "lines" in order to let calm instructions "preprocess" them and then "explicitely" pass them to the assembly stage.
You can keep the lines in symbolic variables (or stacked in a single variable) and the assemble them whenever you wish.

sylware wrote:
Then, in a calm instruction, I don't know how to perform the same thing than the "macro match" with the "calm match", namely simple identifier substitution.
The CALM operations are more fundamental, so for example MATCH only does the actual pattern matching. You can perform an identifier substitution with a two-argument TRANSFORM, although this is not the same as standard preprocessing, because it works on complete identifiers and not their token components.
Post 05 Aug 2021, 13:28
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
stacking "lines" into a variable. I guess you refer to the special "MACRO ?" which will be repeated for each "line" until its END MACRO, that using the stacking operator "=:". Then I guess un-stacking this variable into the calm instruction is using the TAKE calm instruction. But that does not disable the "line" going to the assembly stage after that, as far as I understand it. Then how would you disable those stacked "lines" going to the assembly stage?

As the "simple" substitution, I guess it referes to a full "identifier" (lvl_d.lvl_e.lvl_f) not a single "identifier token" (lvl_e in lvl_d.lvl_e.lvl_f), then good news, the two-argument TRANSFORM should do the trick, but I still don't see how I would write it.
Post 05 Aug 2021, 13:54
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7918
Location: Kraków, Poland
Tomasz Grysztar
sylware wrote:
stacking "lines" into a variable. I guess you refer to the special "MACRO ?" which will be repeated for each "line" until its END MACRO, that using the stacking operator "=:".
Since we are now discussing the option of using CALM, it would be better to use "calminstruction ?" instead of "macro ?". But even if we stick to classic macro, the "=:" operator would not be the one to use, as it is for numeric values. For symbolic ones you'd use EQU or DEFINE (as opposed to REDEFINE and REEQU, which do not stack values).

sylware wrote:
But that does not disable the "line" going to the assembly stage after that, as far as I understand it. Then how would you disable those stacked "lines" going to the assembly stage?
When you intercept the line with "?" macro, nothing else happens with it unless you do it explicitly. See the "macro comment?" example in the manual.

sylware wrote:
As the "simple" substitution, I guess it referes to a full "identifier" (lvl_d.lvl_e.lvl_f) not a single "identifier token" (lvl_e in lvl_d.lvl_e.lvl_f), then good news, the two-argument TRANSFORM should do the trick, but I still don't see how I would write it.
Here's a basic example that does a couple of (case-insensitive) replacements:
Code:
define replace

define replace.is?      =
define replace.show?    display

calminstruction ?! line&
        transform line, replace
        assemble line
end calminstruction

a is $
if a is 0
        show "OK"
end if    
(it needs "calminstruction ?!" instead of "calminstruction ?" in order to catch all the lines, the basic one would not be able to intercept lines containing special source-structuring commands like IF).
Post 05 Aug 2021, 14:17
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 55
Location: Marseille/France
sylware
This should be more than enough for a proper namespace-ized/modular program, all that in a "one assembly unit".

I'll see how all that flows while coding.
Post 06 Aug 2021, 18:54
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


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


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

Website powered by rwasa.