flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > FIX in macro's

Author
Thread Post new topic Reply to topic
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
Privalov,

In old Fasm versions (last one i checked was 1.56) fix was evaluated inside macro expansion, whereas now it is evaluated in macro definition. Is this intended behavior? Since both are preprocessor, the old way seemed more logical... Also it allowed for more preprocessor possibilities...

Example:
Code:
macro m {
 f fix g
}
display `f
m
display `f    

in fasm 1.56 this resulted in: "fg"
in fasm 1.66 this is: "gg"
Post 05 Jun 2006, 12:56
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7718
Location: Kraków, Poland
Tomasz Grysztar
Post 05 Jun 2006, 13:05
View user's profile Send private message Visit poster's website Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
thx for the quick response...
And as long as it is by design, it's ok.
However in that topic you stated that all old uses can be replaced by the new syntax, so could you help me convert one of my old macro's?
Code:
@code fix SECTION.code
@idata fix SECTION.idata
macro SECTION.code {
 SomeSetup
 @code fix SECTION.code
 @idata fix SECTION.idata
}
macro SECTION.idata {
 local o
 SomeSetup
 @code fix \} SECTION.code
 @idata fix \} SECTION.idata
 macro o \{
}    
Post 05 Jun 2006, 13:28
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
Use "define" or "equ". See doc for more info
Post 14 Jun 2006, 14:24
View user's profile Send private message Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
define and equ don't work with }, since it is a preprocessor directive itself...

i see it also is impossible to escape fix to force this behavior (like x \fix y)
the only thing i can currently think of is using the fix in a different file and including that by a macro, like:

Code:
in file1.asm:
@code fix SECTION.code 
@idata fix SECTION.idata 
macro SECTION.code { 
 SomeSetup
 include file2.asm 
} 
macro SECTION.idata { 
 local o 
 SomeSetup
 include file3.asm
 macro o \{ 
}
in file2.asm:
@code fix SECTION.code 
@idata fix SECTION.idata 
in file3.asm:
@code fix } SECTION.code 
@idata fix } SECTION.idata 
    

This should result in what i need right? But this seems way cumbersome, so i'm still waiting on someone else to offer a better solution.
Post 14 Jun 2006, 16:33
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7718
Location: Kraków, Poland
Tomasz Grysztar
Sorry, I thought your problem was somewhere else.
In my opinion you should rather do this this way:
Code:
macro SECTION.code {
 local o
 SomeSetup
 macro o \{
}
; ...

macro initial {

@code fix } SECTION.code
@idata fix } SECTION.idata    


The FIX in its corrected meaning should be rather used as a global setting.

PS. } is not a preprocessor's directive, it's a macro syntax construct. When you are not defining a macro, the preprocessor will kindly ignore it. This leads us to another possible solution:
Code:
@code fix definer } SECTION.code
@idata fix definer } SECTION.idata

macro definer [args] { common match =\}def,args \{ def \} }

macro SECTION.code {
 local o
 SomeSetup
 macro o \{
}
;...    

When no macro is opened, definer will just "execute" the command following } in it arguments.
When "definer" is inside a macro, it will not have any arguments, and thus no match will occur and nothing will happen.


Last edited by Tomasz Grysztar on 14 Jun 2006, 17:07; edited 2 times in total
Post 14 Jun 2006, 16:45
View user's profile Send private message Visit poster's website Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
unfortunatly the code is a bit complex for this approach. it would be used as this:
Code:
@const
 someconsts...
@idata
 initialised data
@udata
 uninitialised data
@code
 code
@import
 imports    


now i only need the } to close a macro in the case the previous section was idata (all the rest don't use a macro)...

so this need to translate in:
Code:
@const
 someconsts...
@idata
 initialised data
}
@udata
 uninitialised data
@code
 code
@import
 imports    
Post 14 Jun 2006, 16:59
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7718
Location: Kraków, Poland
Tomasz Grysztar
Try the solution from my PS above (i added it while you were posting, sorry).
Post 14 Jun 2006, 17:04
View user's profile Send private message Visit poster's website Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
ok i'll look into it, thanks alot!

Priv, i have to hand it to you, i thought i was pretty good with macros by now, but damn, you rock! This works like a charm!
Post 14 Jun 2006, 17:16
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7718
Location: Kraków, Poland
Tomasz Grysztar
And forgive me that my answers was usually given in hurry, before I comprehended exactly what is that you need to achieve.

Today I have updated the Understanding fasm article with a new section, that among other things explains how the new meaning of FIX fits into the whole image. The details given there should explain why even escaping the FIX will not make it work from macro, while it works when including a file. Please let me know if there's in your opinion anything not clear in that article, for me it is right now the most important project in fasm's documentation area.
Post 15 Jun 2006, 12:11
View user's profile Send private message Visit poster's website Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
First of all, no need to apologize!

Now personally i preferred the old usage of fix, but like i said that is a personal preference (it seemed more logical).
However, to make the new usage of fix more clear i would describe it as a seperate pass...
As in: first the entire source is searched for any fix commands and the neccessary replacements are done.
next, all preprocessor commands are evaluated (macro, equ, ...)
then all assembler commands are evaluated.

At the moment you still explain fix as one of the preprocessor instructions, which technicaly is accurate, but logicaly is kinda misleading, cause it is evaluated independent of the preprocess stage.

However, if you choose this as the usage of the keyword (as a sort of extra stage), you might want to eliminate the current usage of fix in included files, as this is clearly not the intended behavior. A quick fix for this, is evaluate include also before macros to force consistant behavior. Although, to be honest, that would limit the current possibilities with include (but as you are quite ingenious, perhaps there are other solutions for these problems).

I hope this is still clear to you, as i had a few beers now. If not i'll clarify more tomorrow... Wink
Post 15 Jun 2006, 20:10
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Quote:
However, to make the new usage of fix more clear i would describe it as a seperate pass...
that's not true. then
Code:
macro dummy {  a fix b }
a    
would produce:
Code:
b    
, which it doesnt'.
Post 15 Jun 2006, 20:15
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7718
Location: Kraków, Poland
Tomasz Grysztar
Actually it's only the context of "line makers" that is able to appropriately explain the FIX. Note that if FIX was processed in a separate stage before doing any other preprocessing, then it would go into the included files (since INCLUDE is a standard preprocessor's directive), and thus it would apply to the main file only. If it was made to apply to each file on load, then the effect would be:
Code:
A fix B
include 'some.inc'
A ; becomes B    

And in 'some.inc':
Code:
A ; stays as A
A fix C
A ; becomes C    


However it is not this way (as it would not be really much usable). The A in first file becomes C, not B, since A gets redefined inside the 'some.inc'. And the first A in 'some.inc' gets replaced with B, as this is the definition of A that is active then.

Thus analogy to separate stage doesn't really explain FIX directive. The "source reading line maker" analogy may do it better.
The line cotinuation backslash character is an example of operator specific to the "source reader", just as # is an operator specific to the macro processor.
And FIX is a specific feature of source reader, just like LOCAL is a specific feature for macro processor.
Post 15 Jun 2006, 22:50
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


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


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.