flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Breaking out of preprocessor loops?

Author
Thread Post new topic Reply to topic
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 22 Apr 2006, 10:30
Is there a way to break out of "rept", "irp" or "irps"? Pls, i need it in a complex expression macro (parses expressions). I found a overkill way, that is, use a boolean symbolic constant to signal if it should process or not, but that is not very good as the ENTIRE list gets processed anyway (even if 90% of elements are not used). So, it would be helpful to know how to break out of these directives (and i must use preprocessor here, not assembler).

if there's no such directive, is it hard to add one. if so, pls tell me some reasons. I'm sorry if there's a strong reason behind it, but I'm confused.

thanks Very Happy
Post 22 Apr 2006, 10:30
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 22 Apr 2006, 11:42
Any such directive would have to be a macro special directive like the "local" one, and thus it would get processed unconditionally just when met. Consider this example:
Code:
rept 4
{
  match +,- 
  \{ 
     local x 
  \}
}    

Since "local" is not escaped, it is recognized by the "rept" macro and thus processed unconditionally. And if it was escaped, it would be the directive for inner "match" macro, not "rept".

Thus the problem lies here in the philosophy of fasm's macros - each one just generates some new source "text" which is processed later, and there are no conditional mechanism for inner macro workings (the "match" directive is just another kind of macro). See the part about macros in my unfinished Understanding fasm arcticle - I hope it is able to make some things more clear. The language of fasm's preprocessor is really different from many of the other interpreted languages (including the fasm's assembler's language, which is quite standard with its IF/WHILE/etc. constructions); it may have something common with LISP, philosophicaly speaking, but this similarity is not really straightforward.
Post 22 Apr 2006, 11:42
View user's profile Send private message Visit poster's website Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 22 Apr 2006, 12:07
This is how I do it (just an example, assume loop? is empty upon entry):

Code:
irps r, a b c d + e f g h i j k l m n o p q r s t u v w - x y z etc
{
  match , loop?
  \{
    ; if we hit the '+' or a '-' symbol, we should break
    match +, r \\{ define loop? + \\}
    match -, r \\{ define loop? + \\}
  \}
}    


this works, but it still iterates even after '+' was found.
how does rept actually work? something like:


Code:
rept 4
{
  match +.-
  \{
    \local x
  \}
}    

translates to (after rept):

Code:
match +,-
{
  local x
}
match +,-
{
  local x
}
match +,-
{
  local x
}
match +,-
{
  local x
}    
or does it process each one completely, and only then repeats?
is it difficult to make rept evaluate the "inner" macros as it processes through it's parameters (i.e on the first step, it sees the "match" is false, so it won't write anything, then it goes to second step, etc... in this way, the "break" could have been done)

sorry if I sound dumb.
have you any ideas how I could make my "irps" better?
thanks for reply, now i understand preprocessor even more Very Happy
Post 22 Apr 2006, 12:07
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 22 Apr 2006, 12:36
The_Grey_Beast wrote:

how does rept actually work? something like:
(...) or does it process each one completely, and only then repeats?

It doesn't really matter how is it done internally - in both those cases the result would be in fact the same. This is the key to understanding what's going on here. The macro produces some lines, and each of those lines may also produce some new lines if it is a macro. But given the definition of a macro and the line that invokes it, there are no other factors that could affect what are the result lines produced by a macro. So the outer macro will generate the same lines no matter whether we expand each of them just when it's generated, or whether we wait till the outer macro finished, and then expand all newly-made lines. Think about - I know it may not be simple, but when you get it, you'll get the essence of fasm's preprocessor understanding.

Note that we have mentioned two different possible implementations of fasm's macro processor, that would still give the same results. I don't officialy state which of those implementations is used - I describe the language, not its implementation. The important point here is that the problems we are discussing are not the result of some possible faults in fasm's implementation of this language, they emerge from the language design itself.

The_Grey_Beast wrote:
is it difficult to make rept evaluate the "inner" macros as it processes through it's parameters (i.e on the first step, it sees the "match" is false, so it won't write anything, then it goes to second step, etc... in this way, the "break" could have been done)

The "match" is something that is generated by macro here, not the thing that would affect the processing of macro itself. Only the operators like "forward", "local" or "#" affect processing of the macro, and their operation is not affected in any way by what has already been generated by given macro, as it was said above.
Post 22 Apr 2006, 12:36
View user's profile Send private message Visit poster's website Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 22 Apr 2006, 12:59
Okay, i get it, then macros can have only fixed number of arguments/etc. (in fact they don't rely on what's inside). thx

anyway, any chance what could make my method better?

I figured that, if I stop only at a given symbol:

Code:
irps r, a b c d + e f g h i j etc
{
  match , loop?
  \{
    match +, r \\{ define loop? + \\}
  \}
}    

I can use this trick:
Code:
match any + blabla, a b c d + e f g h i j etc
{
  irp r, any  ; this will iterate only until '+' Smile
  ...
}    
I know, I should've included "match any +, ..." and "match + blabla, ..." and "match +, ..." too (since '+' can be anywhere), but the idea is there.

what's sad is that with 2 or more symbols (like '+' and '-'), it simply won't work. any other ideas, or should I stick to my original method?
Post 22 Apr 2006, 12:59
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.